# 树是一种数据结构
# 比如目录结构
# 树是一种可以递归定义的数据结构
# 树是由n个节点组成的集合
# 比如n=0,那这是一颗空树
# 如果n>0,那存在1个节点作为树的根节点,其它节点可以分成m个集合,每个集合本身又是一棵树
# 基本概念
# 二叉树:树的度不超过2的树,每个节点最多只有两个孩子节点,分别是左孩子节点和右孩子节点
# 满二叉树,每个层的节点都达到最大值
# 完全二叉树:叶节点只能出现在最下层和次下层,并且最下面一层的结点都集中在该层最左边的若干位置的二叉树
# 二叉树的存储方式
# 1,链式存储方式
# 2.顺序存储方式 (用列表来存储)
# 这里介绍顺序存储方式
# 1.父节点和左孩子节点的编号下标 的下标关系 i=2i+1
# 2.父节点和右孩子节点的编号下标 的下标关系 i=2i+2
# 3.子节点找父节点 整除 int(i-1/2)
# 堆
# 一种完全的二叉树结构
# 大根堆:一颗完全二叉树,满足任一节点都比其他孩子节点大
# 小根堆:一颗完全二叉树,满足任一节点都比其他孩子节点小
# 堆排序:堆的向下调整性质
# 当根节点的左右子树都是堆时,可以通过一次向下的调整来将其变换成一个堆
# 堆排序过程
# 1.建立堆
# 2.得到堆顶元素,为最大顶
# 3.去掉堆顶,将堆最后一个元素放到堆顶,此时可通过一次调整重新使堆有序。
# 4.堆顶元素为第二大元素
# 5.重复步骤3,知道堆变空
def sift(li,low,high):
"""
:param li: 列表
:param low: 堆的堆顶位置
:param high: 堆的最后一个元素位置
:return:
"""
i=low # i最开始指向根节点
j=2*i+1 # j开始是左孩子
tmp=li[low] # 把堆顶存起来
while j<=high: # 只要j位置有数,
if j+1<=high and li[j+1]>li[j]: # 如果右孩子比左孩子大,就把指针指向右边
j=j+1
if li[j]>tmp:
li[i]=li[j]
i=j
j=2*i+1 # 其实就是在当前基础上向下看
else: # tmp更大
break
li[i]=tmp # 把tmp放到叶子节点上
def heap_sort(li):
n=len(li)
for i in range((n-2)//2,-1,-1): # 从n-1开始,倒着遍历到0 (农村包围城市)
# i表示建堆的时候调整的部分的根的下标
sift(li,i,n-1)
# 这列的high的作用就是树的最后一个数字,作用就是判别有没有越界
# 建堆完成
print(li)
for i in range(n-1,-1,-1):
# i 指向堆的最后一个位置
li[0],li[i]=li[i],li[0]
sift(li,0,i-1) # i-1 是新的high
print(li)
li=[i for i in range(100)]
import random
random.shuffle(li)
print(li)
heap_sort(li)
python实现堆排序
最新推荐文章于 2024-06-26 19:29:00 发布
![](https://img-home.csdnimg.cn/images/20240711042549.png)