生活随笔
收集整理的這篇文章主要介紹了
(Ipython)Matplotlib 中将二叉树可视化
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
(注意之前代碼有錯誤目前已更新)
最近學習黑紅二叉樹,我想如果把二叉樹可視化在操作的時候如果出錯會比較容易發現。
在網上搜了一圈只有比較簡單的ascii 的代碼。
自己用Ipython寫了一個,比較適合學生。
PS:算法沒有做優化,加上matplotlib本身就慢,不適合較高的樹。
效果見圖:
?
基本算法:
首先獲取二叉樹的高度 h,二叉樹在所有節點都有左右在子節點的情況下,在高度 y時?X軸包含節點個。
比如 高度 2 有 = 2個節點.
創建一個Y軸長度相同的二維矩陣,X軸包含了所有節點和節點左右的空白區域,長度為 。
在遍歷矩陣中所有元素的時候,如果 坐標 (x,y)中包含了一個節點則檢測它的子節點,這時候把它的子節點放入到二維矩陣當中
如左側子節點坐標為 (x_,y_), ?
y_ ?,
x_的坐標需要計算偏移量,這里稱為 , x_?。
偏移量從樹冠底部到根部是依次乘以2的,在實現可視化的時候如果將樹根底部偏移量設置為1,那么 偏移量的計算公式如下:
由于y在程序中是以0開始的所以python中 matrix 為二維矩陣該計算方式為
dx = 2**(len(matrix) - y?-?2)
獲取到偏移量之后只需要遍歷 y 軸, x軸,
檢測到節點時檢測左右,然后把子節點放置到二維矩陣中即可。
在實現可視化的時候節點已經在矩陣中,提取(x,y)坐標并繪制或者輸出字符串即可
PS:
????? ? 使用二維矩陣是因為數據整理之后比較方便處理,可以繪制也可以直接輸出字符串。
????? ? 如果需要優化直接計算偏移量即可
import matplotlib.pyplot as plt
import matplotlib.lines as mlinesclass Node():def __init__(self):self.is_red = Falseself.left = Noneself.right = Noneself.value = 0def get_height(self): #返回樹高度,未優化算法應該比較慢layers = [self]layer_count = 0while layers:layer_count += 1new_list = []for node in layers:if node.left:new_list.append(node.left)if node.right:new_list.append(node.right)layers = new_listreturn layer_countdef visualize(self,axis='off'):'''基本算法: 將樹狀結構映射到二維矩陣中,如果節點左右下方有節點則把該節點加入到矩陣中的坐標中,如節點(x,y)左下方有節點則把節點放入(x+offset,y+1)offset為x坐標偏移量,offset = 2**(len(matrix)-y-2)'''figure, axes = plt.subplots(figsize=(8, 6), dpi=80)height = self.get_height()width_ = 2**(height-1)width = 2 * width_ + 1matrix = [[[]for x in range(width)] for y in range(height)]matrix[0][width_] = head #put head in the middle positionfor y in range(len(matrix)):for x in range(len(matrix[y])):node = matrix[y][x]if node:x1, y1 = (1/width)*(x+0.5), 1-(1/height)*y-0.2axes.text(x1, y1, str(node.value),color='white',fontsize=FONT_SIZE,fontweight='bold')offset = 2**(len(matrix)-y-2)if node.left:matrix[y+1][x-offset] = node.leftx2,y2 = (1/width)*(x-offset+0.5),1-(1/height)*(y+1)-0.2line = mlines.Line2D([x1,x2], [y1,y2],zorder= -1)axes.add_line(line)if node.right:matrix[y+1][x+offset] = node.rightx2,y2 = (1/width)*(x+offset+0.5),1-(1/height)*(y+1)-0.2line = mlines.Line2D([x1,x2], [y1,y2],zorder= -1)axes.add_line(line)cc = plt.Circle( ((1/width)*(x+0.5), 1-(1/height)*y-0.2 ), 1/width/2*NODE_SIZE_SCALE, color=('r' if node.is_red else 'black' )) axes.set_aspect(1) axes.add_artist(cc,)plt.axis(axis)plt.show()def create_empty_tree():global headhead = Node()head.left = Node()head.left.is_red = Truehead.right = Node()head.right.left = Node()head.left.left = Node()head.left.right = Node()create_empty_tree()FONT_SIZE = 15
NODE_SIZE_SCALE = 0.5
head.visualize()
總結
以上是生活随笔為你收集整理的(Ipython)Matplotlib 中将二叉树可视化的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。