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重试装饰器示例
Feb 11 Python
python3实现短网址和数字相互转换的方法
Apr 28 Python
Python实现的堆排序算法原理与用法实例分析
Nov 22 Python
python2.7安装图文教程
Mar 13 Python
Python操作mongodb数据库的方法详解
Dec 08 Python
详解python持久化文件读写
Apr 06 Python
Flask框架请求钩子与request请求对象用法实例分析
Nov 07 Python
解决Pytorch训练过程中loss不下降的问题
Jan 02 Python
python 穷举指定长度的密码例子
Apr 02 Python
Django实现前台上传并显示图片功能
May 29 Python
Django haystack实现全文搜索代码示例
Nov 28 Python
python中常用的数据结构介绍
Jan 12 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
虹吸式咖啡壶操作
2021/03/03 冲泡冲煮
php strtotime 函数UNIX时间戳
2009/01/14 PHP
基于PHP读取csv文件内容的详解
2013/06/18 PHP
PHP用星号隐藏部份用户名、身份证、IP、手机号等实例
2014/04/08 PHP
PHP Opcache安装和配置方法介绍
2015/05/28 PHP
学习php设计模式 php实现门面模式(Facade)
2015/12/07 PHP
PHP中OpenSSL加密问题整理
2017/12/14 PHP
YII框架关联查询操作示例
2019/04/29 PHP
Yii框架中用response保存cookie,用request读取cookie的原理解析
2019/09/04 PHP
JS+XML 省份和城市之间的联动实现代码
2009/10/14 Javascript
jquery JSON的解析方式示例介绍
2014/07/27 Javascript
优化Node.js Web应用运行速度的10个技巧
2014/09/03 Javascript
jQuery控制元素显示、隐藏、切换、滑动的方法总结
2015/04/16 Javascript
通过jquery实现页面的动画效果(实例代码)
2016/09/18 Javascript
JQuery Ajax 异步操作之动态添加节点功能
2017/05/24 jQuery
bootstrap daterangepicker双日历时间段选择控件详解
2017/06/15 Javascript
JS移动端/H5同时选择多张图片上传并使用canvas压缩图片
2017/06/20 Javascript
Angularjs的启动过程分析
2017/07/18 Javascript
jQuery实现模糊搜索功能的方法分析
2018/06/29 jQuery
JS实现的tab切换并显示相应内容模块功能示例
2019/08/03 Javascript
微信小程序tab切换可滑动切换导航栏跟随滚动实现代码
2019/09/04 Javascript
vue循环数组改变点击文字的颜色
2019/10/14 Javascript
python访问纯真IP数据库的代码
2011/05/19 Python
跟老齐学Python之类的细节
2014/10/13 Python
浅谈Python数据类型判断及列表脚本操作
2016/11/04 Python
python非递归全排列实现方法
2017/04/10 Python
Python利用matplotlib生成图片背景及图例透明的效果
2017/04/27 Python
Python复制Word内容并使用格式设字体与大小实例代码
2018/01/22 Python
Python分支语句与循环语句应用实例分析
2019/05/07 Python
python 使用pygame工具包实现贪吃蛇游戏(多彩版)
2019/10/30 Python
Django2 连接MySQL及model测试实例分析
2019/12/10 Python
AmazeUI 面板的实现示例
2020/08/17 HTML / CSS
英国户外装备和冒险服装零售商:alloutdoor
2018/01/30 全球购物
2014厂务公开实施方案
2014/02/17 职场文书
大课间活动实施方案
2014/03/06 职场文书
培训学校2015年度工作总结
2015/07/20 职场文书