python基础知识学习——⼆叉树的绘制  基于⼆叉堆的⼆叉树绘制⽅法
  注:本⽂所述⽅法中的⼆叉树以链表的形式存储。
  1 绘图前准备。
  ⾸先你的⼆叉树要以链表的形式存储,你的节点类中⽅法的命名要如下所⽰:
  class BinaryTree:
  def __init__(self,value):
  self.value=value
  self.left=None
  self.right=None
  self.indexInHeap=None
  def getIndexHeap(self):
  return self.indexInHeap
  def setIndexHeap(self,value):
  self.indexInHeap=value
  def insertLeft(self,newNode):
  if self.left==None:
  self.left=BinaryTree(newNode)
  else:
  t=BinaryTree(newNode)
  t.left=self.left
  self.left=t
  def insertRight(self,newNode):
  if self.right==None:
  self.right=BinaryTree(newNode)
  else:
  t=BinaryTree(newNode)
  t.right=self.right
  self.right=t
  def getValue(self):
  return self.value
  def setValue(self,value):
  self.value=value
  def getRightChild(self):
  return self.right
  def getLeftChild(self):
  return self.left
  2、绘图的基本思想
  ⾸先通过⼆叉树的⾼度,得出最底层满⼆叉树的叶⼦节点树,随后将该树满⼆叉树的叶节点求出,然后层层向上递推,求出所有节点的坐标,然后存为⼆叉堆数组。同时将你的⼆叉树存为⼆叉堆数组,⼆者⼀⼀对应,通过mathplo的annotate进⾏绘制。
  注:有⼈回复的时候我再介绍详细的思想;
  所有涉及的函数以及简单⽰例如下:
  import matplotlib.pyplot as plt
  from treeClass import myOwnTree
  def getNumberOfLeafs(tree):
  leafNumber = 0##对应none节点
  if tree:
  if RightChild() and LeftChild():
  leafNumber+=1
  else:
  leafNumber+=LeftChild())
  leafNumber += RightChild())
  return leafNumber
  def getDeepOfTree(tree):
  maxDeep=0#不符合情况的那个是0
  if tree:
  maxLeft=LeftChild())
  maxRight=RightChild())
  if maxLeft>maxRight:
  maxDeep=maxLeft
  return 1+maxLeft
  else:
  maxDeep=maxRight
  return 1+maxRight
  return maxDeep
  def printTreePre(tree):
  if tree:
  Value())
  LeftChild())
  RightChild())
  # tree(treeLen-4)
  def getDuiIndex(tree):
  if tree:
  LeftChild():
  LeftChild().setIndexHeap(IndexHeap())
  RightChild():
  RightChild().setIndexHeap(2 * IndexHeap()+1)
二叉树的遍历python  LeftChild())
  RightChild())
  def getDuiHelp(list,tree):
  if tree:
  IndexHeap()]=Value()
  getDuiHelp(LeftChild())
  getDuiHelp(RightChild())
  return list
  def getDuiList(tree):
  getDuiIndex(tree)#给每个节点添加堆序号
  h=getDeepOfTree(tree)
  res=[None for i in range(2**h-1)]
  res.insert(0,0)
  return getDuiHelp(res,tree)
  def drawBinaryTree(r,nodeType=dict(box, fc=(1.0, 0.7, 0.7), ec="none")):
  # 接下来⽤我的⽅式画这个图
  fig = plt.figure(1, facecolor="white")
  fig.clf()
  ax1 = plt.subplot(111, frameon=False)
  h = getDeepOfTree(r)
  if h==1:#如果只有⼀层
  ax1.Value(), va="center", ha="center", xy=(0.5,0.5), bbox=nodeType) ##画出这个点  return None
  w = getNumberOfLeafs(r)
  detH = 1 / (h - 1)
  yAxis = []
  startY = 0
  while startY <= 1:
  yAxis.append(startY)
  startY += detH
  allLeafs = 2 ** (h - 1)
  detX = 1 / (allLeafs - 1)
  leafPos = []
  startX = 0
  while startX <= 1:
  leafPos.append(startX)
  startX += detX
  allXList = []
  while len(leafPos) >= 1:
  allXList.append(leafPos)
  tempList = []
  i = 0
  while i < len(leafPos) - 1:
  tempList.append((leafPos[i] + leafPos[i + 1]) / 2)
  i += 2
  leafPos = tempList
  allXList = allXList[::-1]
  finPos = []
  for xList, y in zip(allXList, yAxis[::-1]):
  for item in xList:
  finPos.append([item, y])
  finPos.insert(0, 0) # 为了使下标满⾜左右⼦树之间的关系,这⾥在开始的位置添加占位符
  ##接下来将⼆叉树存为⼆叉堆的形式
  r.setIndexHeap(1)
  duiListForR = getDuiList(r)
  ##开始画
  for i in range(1, len(duiListForR)):
  if duiListForR[i]:
  ##然后画出这个点指出去的箭头
  if 2*i
  ax1.annotate("", xy=(finPos[i][0], finPos[i][1]),xytext=(finPos[2*i][0],finPos[2*i][1]),va="center",
ha="center",bbox=nodeType,arrowprops=dict(arrow))##画出这个点
  ax1.annotate("", xy=(finPos[i][0], finPos[i][1]),xytext=(finPos[2*i+1][0],finPos[2*i+1][1]),va="center",
ha="center",bbox=nodeType,arrowprops=dict(arrow))##画出这个点
  for i in range(1, len(duiListForR)):
  if duiListForR[i]:
  ax1.annotate(duiListForR[i],va="center", ha="center",xy= (finPos[i][0], finPos[i][1]),bbox=nodeType)##画出这个点  if __name__ == '__main__':
  r = myOwnTree.BinaryTree("a")
  r.insertLeft("b")
  r.insertRight("c")
  r.getRightChild().insertLeft("d")
  r.getRightChild().getLeftChild().insertRight("g")
  r.getLeftChild().insertRight("f")
  r.getLeftChild().insertLeft("h")
  r.getLeftChild().getLeftChild().insertLeft("i")
  r.getLeftChild().getLeftChild().insertRight("k")
  r.getLeftChild().getLeftChild().getLeftChild().insertRight("l")
  r.getLeftChild().getLeftChild().getLeftChild().insertLeft("m")
  # ##⽣成⼀个图⽚,图⽚上进⾏注释
  # toothType=dict(box, fc="0.8")#波浪形
  leafNod=dict(box, fc=(1.0, 0.7, 0.7), ec="none")#圆形
  drawBinaryTree(r,leafNod)
  绘制的效果如下图所⽰:
  3、如果你觉得上⾯写的过于⿇烦
  如果你对绘制和⼆叉树的操作过程不求甚解,只求应⽤的话,我的代码已经上到了git上。  github上的代码
  下载下来之后将⾥⾯的两个⽂件夹拷到你的项⽬⾥,然后就可以直接引⽤了:
  #画图函数
  import drawPicture.viewBinaryTree as binaryView
  #导⼊⼆叉树的构建类
  OwnTree import BinaryTree
  ##随意构建树
  r = BinaryTree("a")
  r.insertLeft("b")
  r.insertRight("c")
  r.getRightChild().insertLeft("d")
  r.getRightChild().getLeftChild().insertRight("g")
  r.getLeftChild().insertRight("f")
  ##画出来
  leafNod=dict(box, fc=(1.0, 0.7, 0.7), ec="none")
  binaryView.drawBinaryTree(r,leafNod)

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。