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中为feedparser设置超时时间避免堵塞
Sep 28 Python
Python中不同进制互相转换(二进制、八进制、十进制和十六进制)
Apr 05 Python
Python写入CSV文件的方法
Jul 08 Python
如何使用Python的Requests包实现模拟登陆
Apr 27 Python
Python排序算法之选择排序定义与用法示例
Apr 29 Python
django rest framework 数据的查找、过滤、排序的示例
Jun 25 Python
python 实现将字典dict、列表list中的中文正常显示方法
Jul 06 Python
PyTorch读取Cifar数据集并显示图片的实例讲解
Jul 27 Python
pyqt5之将textBrowser的内容写入txt文档的方法
Jun 21 Python
使用 Python 在京东上抢口罩的思路详解
Feb 27 Python
Python定时任务框架APScheduler原理及常用代码
Oct 05 Python
详解python日志输出使用配置文件格式
Feb 10 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
php设计模式 State (状态模式)
2011/06/26 PHP
使用php判断网页是否gzip压缩
2013/06/25 PHP
PHP封装CURL扩展类实例
2015/07/28 PHP
PHP中的Session对象如何使用
2015/09/25 PHP
PHP中strncmp()函数比较两个字符串前2个字符是否相等的方法
2016/01/07 PHP
PHP利用二叉堆实现TopK-算法的方法详解
2017/04/24 PHP
php多文件打包下载的实例代码
2017/07/12 PHP
jQuery 1.0.4 - New Wave Javascript(js源文件)
2007/01/15 Javascript
使用Jquery搭建最佳用户体验的登录页面之记住密码自动登录功能(含后台代码)
2011/07/10 Javascript
jQuery 过滤not()与filter()实例代码
2012/05/10 Javascript
JavaScript利用正则表达式去除日期中的-
2014/06/09 Javascript
理运用命名空间让js不产生冲突避免全局变量的泛滥
2014/06/15 Javascript
用console.table()调试javascript
2014/09/04 Javascript
JavaScript的RequireJS库入门指南
2015/07/01 Javascript
js实现的动画导航菜单效果代码
2015/09/10 Javascript
微信小程序 Tab页切换更新数据
2017/01/05 Javascript
jQuery插件ajaxFileUpload使用详解
2017/01/10 Javascript
纯JS实现只能输入数字的简单代码
2017/06/21 Javascript
vue实现的网易云音乐在线播放和下载功能案例
2019/02/18 Javascript
详解jenkins自动化部署vue
2019/05/14 Javascript
微信小程序获取地理位置及经纬度授权代码实例
2019/09/18 Javascript
Python标准库内置函数complex介绍
2014/11/25 Python
python访问系统环境变量的方法
2015/04/29 Python
Python序列循环移位的3种方法推荐
2018/04/09 Python
python实现KNN分类算法
2019/10/16 Python
基于 Python 实践感知器分类算法
2021/01/07 Python
CSS3制作漂亮的照片墙的实现代码
2016/06/08 HTML / CSS
英国比较机场停车场网站:Airport Parking Essentials
2019/12/01 全球购物
世界上最大的字体市场:MyFonts
2020/01/10 全球购物
什么是smarty? Smarty的优点是什么?
2013/08/11 面试题
大学生求职简历的自我评价
2013/10/14 职场文书
建设幸福中国演讲稿
2014/09/11 职场文书
2015年农村党员公开承诺事项
2015/04/28 职场文书
初中班主任心得体会
2016/01/07 职场文书
英语教学课后反思
2016/02/15 职场文书
《最终幻想14》6.01版本4月5日推出 追加新任务新道具
2022/04/03 其他游戏