京公网安备 11010802034615号
经营许可证编号:京B2-20210330
Python实现基于二叉树存储结构的堆排序算法示例
本文实例讲述了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()
运行结果:
数据分析咨询请扫描二维码
若不方便扫码,搜微信号:CDAshujufenxi
在数字化时代,数据已成为企业决策的核心驱动力,数据分析与数据挖掘作为解锁数据价值的关键手段,广泛应用于互联网、金融、医疗 ...
2026-04-17在数据处理、后端开发、报表生成与自动化脚本中,将 SQL 查询结果转换为字符串是一项高频且实用的操作。无论是拼接多行数据为逗 ...
2026-04-17面对一份上万行的销售明细表,要快速回答“哪个地区卖得最好”“哪款产品增长最快”“不同客户类型的购买力如何”——这些看似复 ...
2026-04-17数据分析师一天的工作,80% 的时间围绕表格结构数据展开。从一张销售明细表到一份完整的分析报告,表格结构数据贯穿始终。但你真 ...
2026-04-16在机器学习无监督学习领域,Kmeans聚类因其原理简洁、计算高效、可扩展性强的优势,成为数据聚类任务中的主流算法,广泛应用于用 ...
2026-04-16在机器学习建模实践中,特征工程是决定模型性能的核心环节之一。面对高维数据集,冗余特征、无关特征不仅会增加模型训练成本、延 ...
2026-04-16在数字化时代,用户是产品的核心资产,用户运营的本质的是通过科学的指标监测、分析与优化,实现“拉新、促活、留存、转化、复购 ...
2026-04-15在企业数字化转型、系统架构设计、数据治理与AI落地过程中,数据模型、本体模型、业务模型是三大核心基础模型,三者相互支撑、各 ...
2026-04-15数据分析师的一天,80%的时间花在表格数据上,但80%的坑也踩在表格数据上。 如果你分不清数值型和文本型的区别,不知道数据从哪 ...
2026-04-15在人工智能与机器学习落地过程中,模型质量直接决定了应用效果的优劣——无论是分类、回归、生成式模型,还是推荐、预测类模型, ...
2026-04-14在Python网络编程、接口测试、爬虫开发等场景中,HTTP请求的发送与响应处理是核心需求。Requests库作为Python生态中最流行的HTTP ...
2026-04-14 很多新人学完Python、SQL,拿到一张Excel表还是不知从何下手。 其实,90%的商业分析问题,都藏在表格的结构里。 ” 引言:为 ...
2026-04-14在回归分析中,因子(即自变量)的筛选是构建高效、可靠回归模型的核心步骤——实际分析场景中,往往存在多个候选因子,其中部分 ...
2026-04-13在机器学习模型开发过程中,过拟合是制约模型泛化能力的核心痛点——模型过度学习训练数据中的噪声与偶然细节,导致在训练集上表 ...
2026-04-13在数据驱动商业升级的今天,商业数据分析已成为企业精细化运营、科学决策的核心手段,而一套规范、高效的商业数据分析总体流程, ...
2026-04-13主讲人简介 张冲,海归统计学硕士,CDA 认证数据分析师,前云南白药集团资深数据分析师,自媒体 Python 讲师,全网课程播放量破 ...
2026-04-13在数据可视化与业务分析中,同比分析是衡量业务发展趋势、识别周期波动的核心手段,其核心逻辑是将当前周期数据与上年同期数据进 ...
2026-04-13在机器学习模型的落地应用中,预测精度并非衡量模型可靠性的唯一标准,不确定性分析同样不可或缺。尤其是在医疗诊断、自动驾驶、 ...
2026-04-10数据本身是沉默的,唯有通过有效的呈现方式,才能让其背后的规律、趋势与价值被看见、被理解、被运用。统计制图(数据可视化)作 ...
2026-04-10在全球化深度发展的今天,跨文化传播已成为连接不同文明、促进多元共生的核心纽带,其研究核心围绕“信息传递、文化解读、意义建 ...
2026-04-09