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实现简单的TCP代理服务器
Oct 08 Python
Python实现模拟登录及表单提交的方法
Jul 25 Python
Python探索之静态方法和类方法的区别详解
Oct 27 Python
python实现跨excel的工作表sheet之间的复制方法
May 03 Python
Python常见MongoDB数据库操作实例总结
Jul 24 Python
Python中矩阵创建和矩阵运算方法
Aug 04 Python
pycharm恢复默认设置或者是替换pycharm的解释器实例
Oct 29 Python
python+opencv实现高斯平滑滤波
Jul 21 Python
pygame库实现移动底座弹球小游戏
Apr 14 Python
python读取raw binary图片并提取统计信息的实例
Jan 09 Python
Anaconda3+tensorflow2.0.0+PyCharm安装与环境搭建(图文)
Feb 18 Python
pyspark 随机森林的实现
Apr 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中Cannot send session cache limiter 的问题的方法
2007/04/27 PHP
PHP函数篇之掌握ord()与chr()函数应用
2011/12/05 PHP
php通过淘宝API查询IP地址归属等信息
2015/12/25 PHP
php+resumablejs实现的分块上传 断点续传功能示例
2017/04/18 PHP
laravel model模型定义实现开启自动管理时间created_at,updated_at
2019/10/17 PHP
显示、隐藏密码
2006/07/01 Javascript
xheditor与validate插件冲突的解决方案
2010/04/15 Javascript
JS 实现点击a标签的时候让其背景更换
2013/10/15 Javascript
谷歌浏览器不支持showModalDialog模态对话框的解决方法
2014/09/22 Javascript
Javascript模拟加速运动与减速运动代码分享
2014/12/11 Javascript
jquery获取当前日期的方法
2015/01/14 Javascript
利用yarn代替npm管理前端项目模块依赖的方法详解
2017/09/04 Javascript
微信小程序 按钮滑动的实现方法
2017/09/27 Javascript
全面介绍vue 全家桶和项目实例
2017/12/27 Javascript
angular.js实现列表orderby排序的方法
2018/10/02 Javascript
详解JavaScript 浮点数运算的精度问题
2019/07/23 Javascript
node使用request请求的方法
2019/12/20 Javascript
JavaScript中跨域问题的深入理解
2021/03/04 Javascript
python使用win32com在百度空间插入html元素示例
2014/02/20 Python
Python学习入门之区块链详解
2017/07/25 Python
python虚拟环境的安装配置图文教程
2017/10/20 Python
Python_LDA实现方法详解
2017/10/25 Python
python版本的仿windows计划任务工具
2018/04/30 Python
pandas 时间格式转换的实现
2019/07/06 Python
用python给自己做一款小说阅读器过程详解
2019/07/11 Python
PyCharm中代码字体大小调整方法
2019/07/29 Python
浅谈amaze-ui中datepicker和datetimepicker注意的几点
2020/08/21 HTML / CSS
李维斯法国官网:Levi’s法国
2019/07/13 全球购物
描述JSP和Servlet的区别、共同点、各自应用的范围
2012/10/02 面试题
汽车装潢店创业计划书范文
2014/02/05 职场文书
《乌鸦和狐狸》教学反思
2014/02/08 职场文书
党的群众路线教育实践活动对照检查材料思想汇报(党员篇)
2014/09/25 职场文书
学习十八大标语
2014/10/09 职场文书
先进党支部事迹材料2016
2016/02/26 职场文书
《弟子规》读后感:知廉耻、明是非、懂荣辱、辨善恶
2019/12/03 职场文书
教你怎么用Python实现多路径迷宫
2021/04/29 Python