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如何通过protobuf实现rpc
Mar 06 Python
Python使用回溯法子集树模板获取最长公共子序列(LCS)的方法
Sep 08 Python
python+Splinter实现12306抢票功能
Sep 25 Python
几行Python代码爬取3000+上市公司的信息
Jan 24 Python
Django集成搜索引擎Elasticserach的方法示例
Jun 04 Python
python print出共轭复数的方法详解
Jun 25 Python
python读取并写入mat文件的方法
Jul 12 Python
10分钟教你用python动画演示深度优先算法搜寻逃出迷宫的路径
Aug 12 Python
python wav模块获取采样率 采样点声道量化位数(实例代码)
Jan 22 Python
Python3搭建http服务器的实现代码
Feb 11 Python
浅析python字符串前加r、f、u、l 的区别
Jan 24 Python
pytorch 实现多个Dataloader同时训练
May 29 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
特详细的PHPMYADMIN简明安装教程
2008/08/01 PHP
php in_array 函数使用说明与in_array需要注意的地方说明
2010/04/13 PHP
PHP面向对象的进阶学习(抽像类、接口、final、类常量)
2012/05/07 PHP
PHP实现的DES加密解密封装类完整实例
2017/04/29 PHP
JavaScript版TAB选项卡效果实例
2013/08/16 Javascript
JS对select控件option选项的增删改查示例代码
2013/10/21 Javascript
JS 删除字符串最后一个字符的实现代码
2014/02/20 Javascript
运用jQuery定时器的原理实现banner图片切换
2014/10/22 Javascript
通过伪协议解决父页面与iframe页面通信的问题
2015/04/05 Javascript
javascript实现英文首字母大写
2015/04/23 Javascript
javascript设计模式之对象工厂函数与构造函数详解
2015/07/30 Javascript
Bootstrap实现下拉菜单效果
2016/04/29 Javascript
微信小程序 Video API实例详解
2016/10/02 Javascript
JS自定义混合Mixin函数示例
2016/11/26 Javascript
Input文本框随着输入内容多少自动延伸的实现
2017/02/15 Javascript
微信小程序实现下载进度条的方法
2017/12/08 Javascript
使用JavaScript实现node.js中的path.join方法
2018/08/12 Javascript
vue框架下部署上线后刷新报404问题的解决方案(推荐)
2019/04/03 Javascript
Vue props中Object和Array设置默认值操作
2020/07/30 Javascript
vue路由分文件拆分管理详解
2020/08/13 Javascript
python获取指定时间差的时间实例详解
2017/04/11 Python
python 借助numpy保存数据为csv格式的实现方法
2018/07/04 Python
Python学习笔记之抓取某只基金历史净值数据实战案例
2019/06/03 Python
Python 寻找局部最高点的实现
2019/12/05 Python
python输出数组中指定元素的所有索引示例
2019/12/06 Python
pytorch之添加BN的实现
2020/01/06 Python
阿迪达斯奥地利官方商城:adidas.at
2016/10/16 全球购物
新加坡网上花店:FlowerAdvisor新加坡
2018/10/05 全球购物
The North Face北面德国官网:美国著名户外品牌
2018/12/12 全球购物
eBay荷兰购物网站:eBay.nl
2020/06/26 全球购物
实习生体会的自我评价范文
2013/11/28 职场文书
销售会计工作职责
2013/12/02 职场文书
党员干部2014全国两会学习心得体会
2014/03/10 职场文书
驾驶员培训方案
2014/05/01 职场文书
2016年七夕爱情寄语
2015/12/04 职场文书
ORACLE数据库对long类型字段进行模糊匹配的解决思路
2021/04/07 Oracle