定義獲取畫二叉樹必要資訊的方法
最後來畫圖
第一次寫部落格哈哈哈哈哈
最近實驗題目多涉及二叉樹,每次除錯在監視視窗檢視二叉樹需要挨個挨個點,十分麻煩,於是就想直接將二叉樹畫出來看看,比較直觀。
為了避免重合,二叉樹左右子樹的距離是關鍵
讓每乙個節點占用乙個列空間,這樣就不會重合了
所以左節點與父節點在x軸上的距離為 左節點 的 右子樹寬度+1 乘以乙個水平距離常數
右節點與父節點在x軸上的距離為 右節點 的 左子樹寬度+1 乘以乙個水平距離常數
每當畫好乙個節點點,確定其左右孩子在x軸上的距離,再畫這個節點連線孩子的邊
random_tree.py
class
treenode()
:def
__init__
(self, x)
: self.val = x
self.left =
none
self.right =
none
**很簡單,我就不廢話了
def
generate_random_tree_by_mid
(mid)
:'''根據中序序列生成隨機bt'''
iflen
(mid)==0
:return
none
root = treenode(random.choice(mid)
) index = mid.index(root.val)
root.left = generate_random_tree_by_mid(mid[
:index]
) root.right = generate_random_tree_by_mid(mid[index+1:
])return root
bst的中序是乙個有序的序列,若不生成bst,則將列表打亂
def
generate_random_tree
(n, isbst =
false):
'''生成隨機形狀和隨機值的bt或bst'''
numbers =
[x for x in
range(1
,200)]
mid =
for _ in
range
(n):
)if isbst:
mid.sort(
)else
: random.shuffle(mid)
root = generate_random_tree_by_mid(mid)
return root
關於樹的方法,基本上可以用遞迴實現
get_params.py
from random_tree import treenode
defget_left_width
(root)
:'''獲得根左邊寬度'''
return get_width(root.left)
defget_right_width
(root)
:'''獲得根右邊寬度'''
return get_width(root.right)
defget_width
(root)
:'''獲得樹的寬度'''
if root ==
none
:return
0return get_width(root.left)+1
+ get_width(root.right)
defget_height
(root)
:'''獲得二叉樹的高度'''
if root ==
none
:return
0return
max(get_height(root.left)
, get_height(root.right))+
1
這裡用到了matplotlib.pyplot來畫圖
圓形來自 matplotlib.patches中的circle
show_btree.py
d_hor =
4#節點水平距離
d_vec =
8#節點垂直距離
radius =
2#節點的半徑
呼叫get_params.py的方法獲取樹的高度和寬度,用來設定畫圖的尺寸
尺寸跟隨樹的 寬 高 動態變化
def
get_w_h
(root)
:'''返回樹的寬度和高度'''
w = get_width(root)
h = get_height(root)
return w, h
畫點需要點的x, y 座標, 點的值
def
draw_a_node
(x, y, val, ax)
:'''畫乙個節點'''
c_node = circle(
(x,y)
, radius=radius, color=
'green'
) ax.add_patch(c_node)
plt.text(x, y,
'%d'
% val, ha=
'center'
, va=
'bottom'
,fontsize=11)
defdraw_a_edge
(x1, y1, x2, y2, r=radius)
:'''畫一條邊'''
x =(x1, x2)
y =(y1, y2)
plt.plot(x, y,
'k-'
)
def
create_win
(root)
:'''建立視窗'''
weight, height = get_w_h(root)
weight =
(weight+1)
*d_hor
height =
(height+1)
*d_vec
fig = plt.figure(figsize=(11
,9))
ax = fig.add_subplot(
111)
plt.xlim(
0, weight)
plt.ylim(
0, height)
x =(get_left_width(root)+1
)* d_hor #x, y 是第乙個要繪製的節點座標,由其左子樹寬度決定
y = height - d_vec
return fig, ax, x, y
採用中序遍歷,根據其他節點與父節點的相對位置,畫出節點
def
print_tree_by_inorder
(root, x, y, ax)
:'''通過中序遍歷列印二叉樹'''
if root ==
none
:return
draw_a_node(x, y, root.val, ax)
lx = rx =
0 ly = ry = y - d_vec
if root.left !=
none
: lx = x - d_hor *
(get_right_width(root.left)+1
)#x-左子樹的右邊寬度
draw_a_edge(x, y, lx, ly, radius)
if root.right !=
none
: rx = x + d_hor *
(get_left_width(root.right)+1
)#x-右子樹的左邊寬度
draw_a_edge(x, y, rx, ry, radius)
#遞迴列印
print_tree_by_inorder(root.left, lx, ly, ax)
print_tree_by_inorder(root.right, rx, ry, ax)
先畫視窗,再畫樹
def
show_btree
(root)
:'''視覺化二叉樹'''
_, ax, x, y = create_win(root)
print_tree_by_inorder(root, x, y, ax)
plt.show(
)def
main()
: root = random_tree.generate_random_tree(50,
true
) show_btree(root)
if __name__ ==
'__main__'
: main(
)
樣例列印了一棵有50個節點的bst
二叉樹列印
舉例 1.初始化時,last 1,把1放入佇列 2.將1出隊,把1的子孩子2,3放入佇列,更新nlast 3 3.nlast更新完之後,列印上一次出隊的1,並和last比較,如果相同就列印換行,並更新last nlast 3 4.將2出隊,把2的子孩子4放入佇列,更新nlast 4 5,nlast更...
二叉樹列印
給定一顆二叉樹的頭節點head,請按照現在大家看到的這種格式列印 要求列印成 12 主要解決的問題是 如何換行 last 表示正在列印的當前行的最右節點 從左至右遍歷,如果遍歷到last節點,說明該換行了,換行之後,只需要nlast last,繼續下一行的列印過程,一直重複,直到所有的節點都列印完。...
列印二叉樹
之前在了解二叉樹旋轉的時候,為了方便檢視中間狀態,就寫了個以樹狀形式列印二叉樹的函式。起初是使用二叉樹中序遍歷的結果展開的方式,簡單但列印出來的樹有一定的傾斜。例如這棵樹 5 3 7 2 6 8它的中序遍歷結果為 2 3 5 6 7 8 列印出來的結果中,節點 3 和節點 7 不是對稱的。因為節點 ...