Python实现基于二叉树存储结构的堆排序算法示例


Posted in Python onDecember 08, 2017

本文实例讲述了Python实现基于二叉树存储结构的堆排序算法。分享给大家供大家参考,具体如下:

既然用Python实现了二叉树,当然要写点东西练练手。

网络上堆排序的教程很多,但是却几乎都是以数组存储的数,直接以下标访问元素,当然这样是完全没有问题的,实现简单,访问速度快,也容易理解。

但是以练手的角度来看,我还是写了一个二叉树存储结构的堆排序

其中最难的问题就是交换二叉树中两个节点。

因为一个节点最多与三个节点相连,那么两个节点互换,就需要考虑到5个节点之间的关系,也需要判断是左右孩子,这将是十分繁琐的,也很容易出错。

class Tree:
  def __init__(self, val = '#', left = None, right = None):
    self.val = val
    self.left = left
    self.right = right
    self.ponit = None
    self.father = None
    self.counter = 0
  #前序构建二叉树
  def FrontBuildTree(self):
    temp = input('Please Input: ')
    node = Tree(temp)
    if(temp != '#'):
      node.left = self.FrontBuildTree()
      node.right = self.FrontBuildTree()
    return node#因为没有引用也没有指针,所以就把新的节点给返回回去
    #前序遍历二叉树
  def VisitNode(self):
    print(self.val)
    if(self.left != None):
      self.left.VisitNode()
    if(self.right != None):
      self.right.VisitNode()
  #中序遍历二叉树
  def MVisitTree(self):
    if(self.left != None):
      self.left.MVisitTree()
    print(self.val)
    if(self.right != None):
      self.right.MVisitTree()
  #获取二叉树的第dec个节点
  def GetPoint(self, dec):
    road = str(bin(dec))[3:]
    p = self
    for r in road:
      if (r == '0'):
        p = p.left
      else:
        p = p.right
    #print('p.val = ', p.val)
    return p
  #构建第一个堆
  def BuildHeadTree(self, List):
    for val in List:
      #print('val = ', val, 'self.counter = ', self.counter)
      self.ponit = self.GetPoint(int((self.counter + 1) / 2))
      #print('self.ponit.val = ', self.ponit.val)
      if (self.counter == 0):
        self.val = val
        self.father = self
      else:
        temp = self.counter + 1
        node = Tree(val)
        node.father = self.ponit
        if(temp % 2 == 0):#新增节点为左孩子
          self.ponit.left = node
        else:
          self.ponit.right = node
        while(temp != 0):
          if (node.val < node.father.val):#如果新增节点比其父亲节点值要大
            p = node.father#先将其三个链子保存起来
            LeftTemp = node.left
            RightTemp = node.right
            if (p.father != p):#判断其不是头结点
              if (int(temp / 2) % 2 == 0):#新增节点的父亲为左孩子
                p.father.left = node
              else:
                p.father.right = node
              node.father = p.father
            else:
              node.father = node#是头结点则将其father连向自身
              node.counter = self.counter
              self = node
            if(temp % 2 == 0):#新增节点为左孩子
              node.left = p
              node.right = p.right
              if (p.right != None):
                p.right.father = node
            else:
              node.left = p.left
              node.right = p
              if (p.left != None):
                p.left.father = node
            p.left = LeftTemp
            p.right = RightTemp
            p.father = node
            temp = int(temp / 2)
            #print('node.val = ', node.val, 'node.father.val = ', node.father.val)
            #print('Tree = ')
            #self.VisitNode()
          else:
            break;
      self.counter += 1
    return self
  #将头结点取出后重新调整堆
  def Adjust(self):
    #print('FrontSelfTree = ')
    #self.VisitNode()
    #print('MSelfTree = ')
    #self.MVisitTree()
    print('Get ', self.val)
    p = self.GetPoint(self.counter)
    #print('p.val = ', p.val)
    #print('p.father.val = ', p.father.val)
    root = p
    if (self.counter % 2 == 0):
      p.father.left = None
    else:
      p.father.right = None
    #print('self.left = ', self.left.val)
    #print('self.right = ', self.right.val)
    p.father = p#将二叉树最后一个叶子节点移到头结点
    p.left = self.left
    p.right = self.right
    while(1):#优化是万恶之源
      LeftTemp = p.left
      RightTemp = p.right
      FatherTemp = p.father
      if (p.left != None and p.right !=None):#判断此时正在处理的结点的左后孩子情况
        if (p.left.val < p.right.val):
          next = p.left
        else:
          next = p.right
        if (p.val < next.val):
          break;
      elif (p.left == None and p.right != None and p.val > p.right.val):
        next = p.right
      elif (p.right == None and p.left != None and p.val > p.left.val):
        next = p.left
      else:
        break;
      p.left = next.left
      p.right = next.right
      p.father = next
      if (next.left != None):#之后就是一系列的交换节点的链的处理
        next.left.father = p
      if (next.right != None):
        next.right.father = p
      if (FatherTemp == p):
        next.father = next
        root = next
      else:
        next.father == FatherTemp
        if (FatherTemp.left == p):
          FatherTemp.left = next
        else:
          FatherTemp.right = next
      if (next == LeftTemp):
        next.right = RightTemp
        next.left = p
        if (RightTemp != None):
          RightTemp.father = next
      else:
        next.left = LeftTemp
        next.right = p
        if (LeftTemp != None):
          LeftTemp.father = next
      #print('Tree = ')
      #root.VisitNode()
    root.counter = self.counter - 1
    return root
if __name__ == '__main__':
  print("三水点靠木测试结果")
  root = Tree()
  number = [-1, -1, 0, 0, 0, 12, 22, 3, 5, 4, 3, 1, 6, 9]
  root = root.BuildHeadTree(number)
  while(root.counter != 0):
    root = root.Adjust()

运行结果:

Python实现基于二叉树存储结构的堆排序算法示例

Python 相关文章推荐
python中将字典转换成其json字符串
Jul 16 Python
举例讲解如何在Python编程中进行迭代和遍历
Jan 19 Python
利用python实现xml与数据库读取转换的方法
Jun 17 Python
基于Django用户认证系统详解
Feb 21 Python
pandas Dataframe行列读取的实例
Jun 08 Python
python删除文件夹下相同文件和无法打开的图片
Jul 16 Python
python return逻辑判断表达式实现解析
Dec 02 Python
opencv python如何实现图像二值化
Feb 03 Python
python字符串下标与切片及使用方法
Feb 13 Python
python代码xml转txt实例
Mar 10 Python
Python3操作YAML文件格式方法解析
Apr 10 Python
分享unittest单元测试框架中几种常用的用例加载方法
Dec 02 Python
Python排序搜索基本算法之堆排序实例详解
Dec 08 #Python
基于Django contrib Comments 评论模块(详解)
Dec 08 #Python
Python数据分析中Groupby用法之通过字典或Series进行分组的实例
Dec 08 #Python
python在ubuntu中的几种安装方法(小结)
Dec 08 #Python
Python编程之gui程序实现简单文件浏览器代码
Dec 08 #Python
Python中的pygal安装和绘制直方图代码分享
Dec 08 #Python
python的unittest测试类代码实例
Dec 07 #Python
You might like
计算2000年01月01日起到指定日的天数
2006/10/09 PHP
PHP集成FCK的函数代码
2008/09/27 PHP
php将fileterms函数返回的结果变成可读的形式
2011/04/21 PHP
简单的cookie计数器实现源码
2013/06/07 PHP
PHP实现返回JSON和XML的类分享
2015/01/28 PHP
PHP实现微信提现功能(微信商城)
2019/11/21 PHP
javascript实现自动输出文本(打字特效)
2015/08/27 Javascript
JavaScript实现图片自动加载的瀑布流效果
2016/04/11 Javascript
jquery实现拖动效果
2016/08/10 Javascript
通过JS和PHP两种方法判断用户请求时使用的浏览器类型
2016/09/01 Javascript
详解VUE的状态控制与延时加载刷新
2017/03/27 Javascript
JS全角与半角转化实例(分享)
2017/07/04 Javascript
浅谈Angular 观察者模式理解
2018/11/01 Javascript
微信小程序通过一个json实现分享朋友圈图片
2019/09/03 Javascript
解决layer弹出层中表单不起作用的问题
2019/09/09 Javascript
微信小程序音乐播放器开发
2019/11/20 Javascript
微信小程序组件生命周期的踩坑记录
2021/03/03 Javascript
[03:17]史诗级大片应援2018DOTA2国际邀请赛 致敬每一位坚守遗迹的勇士
2018/07/20 DOTA
python自动格式化json文件的方法
2015/03/11 Python
python实现从字典中删除元素的方法
2015/05/04 Python
python用BeautifulSoup库简单爬虫实例分析
2018/07/30 Python
python十进制转二进制的详解
2020/02/07 Python
Python判断三段线能否构成三角形的代码
2020/04/12 Python
Python自动化测试中yaml文件读取操作
2020/08/20 Python
HTML5 拖放(Drag 和 Drop)详解与实例代码
2017/09/14 HTML / CSS
新西兰最大的在线设计师眼镜店:SmartBuyGlasses新西兰
2017/10/20 全球购物
Boom手表官网:瑞典手表品牌,设计你的手表
2019/03/11 全球购物
奥林匹亚体育:Olympia Sports
2020/12/30 全球购物
最热门的自我评价
2013/12/30 职场文书
《春晓》教学反思
2014/04/20 职场文书
体育专业大学生职业生涯规划范文:打造自己的运动帝国
2014/09/12 职场文书
中共广东省委常委会党的群众路线教育实践活动整改方案
2014/09/23 职场文书
企业法人代表授权委托书
2014/10/02 职场文书
会计岗位职责
2015/02/03 职场文书
Keras在mnist上的CNN实践,并且自定义loss函数曲线图操作
2021/05/25 Python
python 网络编程要点总结
2021/06/18 Python