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不规范的日期字符串处理类
Jun 10 Python
Python下载懒人图库JavaScript特效
May 28 Python
判断网页编码的方法python版
Aug 12 Python
Python 基础教程之闭包的使用方法
Sep 29 Python
python DataFrame 修改列的顺序实例
Apr 10 Python
基于Python列表解析(列表推导式)
Jun 23 Python
详解Python列表赋值复制深拷贝及5种浅拷贝
May 15 Python
Python队列、进程间通信、线程案例
Oct 25 Python
python基于property()函数定义属性
Jan 22 Python
Django模型中字段属性choice使用说明
Mar 30 Python
Python连接mysql数据库及简单增删改查操作示例代码
Aug 03 Python
linux中nohup和后台运行进程查看及终止
Jun 24 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计算页面执行时间的实现代码
2013/06/18 PHP
PHP基于反射机制实现插件的可插拔设计详解
2016/11/10 PHP
PHP基于DOMDocument解析和生成xml的方法分析
2017/07/17 PHP
PDO::errorInfo讲解
2019/01/28 PHP
PHP实现无限极分类的两种方式示例【递归和引用方式】
2019/03/25 PHP
基于jquery实现的服务器验证控件的启用和禁用代码
2010/04/27 Javascript
xml文档转换工具,附图表例子(hta)
2010/11/17 Javascript
贴近用户体验的Jquery日期、时间选择插件
2015/08/19 Javascript
JS中append字符串包含onclick无效传递参数失败的解决方案
2016/12/26 Javascript
nodejs+websocket实时聊天系统改进版
2017/05/18 NodeJs
解决vue-cli + webpack 新建项目出错的问题
2018/03/20 Javascript
jQuery操作attr、prop、val()/text()/html()、class属性
2019/05/23 jQuery
Jquery 动态添加元素并添加点击事件实现过程解析
2019/10/12 jQuery
[04:56]经典回顾:前Ehome 与 前LGD
2015/02/26 DOTA
Python中dictionary items()系列函数的用法实例
2014/08/21 Python
Python脚本实现集群检测和管理功能
2015/03/06 Python
Python实现SVN的目录周期性备份实例
2015/07/17 Python
基于随机梯度下降的矩阵分解推荐算法(python)
2018/08/31 Python
Python3爬取英雄联盟英雄皮肤大图实例代码
2018/11/14 Python
简单了解python变量的作用域
2019/07/30 Python
python实现宿舍管理系统
2019/11/22 Python
python二维键值数组生成转json的例子
2019/12/06 Python
Python3操作MongoDB增册改查等方法详解
2020/02/10 Python
Django 删除upload_to文件的步骤
2020/03/30 Python
sklearn和keras的数据切分与交叉验证的实例详解
2020/06/19 Python
matplotlib教程——强大的python作图工具库
2020/10/15 Python
html5音频_动力节点Java学院整理
2018/08/22 HTML / CSS
美国顶级防滑鞋:Shoes For Crews
2017/03/27 全球购物
Sephora丝芙兰菲律宾官方网站:购买化妆品和护肤品
2017/04/05 全球购物
如何用Lucene索引数据库
2016/02/23 面试题
艺术设计专业个人求职信范文
2013/12/11 职场文书
教师节活动总结
2014/08/29 职场文书
2015年绩效考核工作总结
2015/05/23 职场文书
2015年学校教研室主任工作总结
2015/07/20 职场文书
laravel添加角色和模糊搜索功能的实现代码
2021/06/22 PHP
Java 轮询锁使用时遇到问题
2022/05/11 Java/Android