用pyplot列印二叉樹,實現二叉樹的視覺化

2021-09-02 20:33:21 字數 4730 閱讀 2564

定義獲取畫二叉樹必要資訊的方法

最後來畫圖

第一次寫部落格哈哈哈哈哈

最近實驗題目多涉及二叉樹,每次除錯在監視視窗檢視二叉樹需要挨個挨個點,十分麻煩,於是就想直接將二叉樹畫出來看看,比較直觀。

為了避免重合,二叉樹左右子樹的距離是關鍵

讓每乙個節點占用乙個列空間,這樣就不會重合了

所以左節點與父節點在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 不是對稱的。因為節點 ...