zoukankan      html  css  js  c++  java
  • 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 not tree.getRightChild() and not tree.getLeftChild():

      leafNumber+=1

      else:

      leafNumber+=getNumberOfLeafs(tree.getLeftChild())

      leafNumber += getNumberOfLeafs(tree.getRightChild())

      return leafNumber

      def getDeepOfTree(tree):

      maxDeep=0#不符合情况的那个是0

      if tree:

      maxLeft=getDeepOfTree(tree.getLeftChild())

      maxRight=getDeepOfTree(tree.getRightChild())

      if maxLeft>maxRight:

      maxDeep=maxLeft

      return 1+maxLeft

      else:

      maxDeep=maxRight

      return 1+maxRight

      return maxDeep

      def printTreePre(tree):

      if tree:

      print(tree.getValue())

      printTreePre(tree.getLeftChild())

      printTreePre(tree.getRightChild())

      # tree(treeLen-4)

      def getDuiIndex(tree):

      if tree:

      if tree.getLeftChild():

      tree.getLeftChild().setIndexHeap(2*tree.getIndexHeap())

      if tree.getRightChild():

      tree.getRightChild().setIndexHeap(2 * tree.getIndexHeap()+1)

      getDuiIndex(tree.getLeftChild())

      getDuiIndex(tree.getRightChild())

      def getDuiHelp(list,tree):

      if tree:

      list[tree.getIndexHeap()]=tree.getValue()

      getDuiHelp(list,tree.getLeftChild())

      getDuiHelp(list,tree.getRightChild())

      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(boxstyle="round", 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.annotate(r.getValue(), 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(arrowstyle="<-"))##画出这个点

      if 2*i+1郑州哪个医院做人流好 http://www.hnmt120.com/

      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(arrowstyle="<-"))##画出这个点

      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(boxstyle="sawtooth", fc="0.8")#波浪形

      leafNod=dict(boxstyle="round", fc=(1.0, 0.7, 0.7), ec="none")#圆形

      drawBinaryTree(r,leafNod)

      绘制的效果如下图所示:

      3、如果你觉得上面写的过于麻烦

      如果你对绘制和二叉树的操作过程不求甚解,只求应用的话,我的代码已经上到了git上。

      github上的代码

      下载下来之后将里面的两个文件夹拷到你的项目里,然后就可以直接引用了:

      #画图函数

      import drawPicture.viewBinaryTree as binaryView

      #导入二叉树的构建类

      from treeClass.myOwnTree 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(boxstyle="round", fc=(1.0, 0.7, 0.7), ec="none")

      binaryView.drawBinaryTree(r,leafNod)

  • 相关阅读:
    JAVA对象之生
    单表扫描,MySQL索引选择不正确 并 详细解析OPTIMIZER_TRACE格式
    [MySQL 5.6] 初识5.6的optimizer trace
    [MySQL5.6] 一个简单的optimizer_trace示例
    PERFORMANCE_SCHEMA 详解
    MetaData Lock 杨奇龙 ---MYSQL博客专家
    ArcEngine控制台应用程序
    一位数据科学家的私房工具清单
    数据可视化之热力图
    数据可视化之MarkPoint
  • 原文地址:https://www.cnblogs.com/djw12333/p/12467972.html
Copyright © 2011-2022 走看看