堆
堆实际上是一棵完全二叉树
完全二叉树(Complete Binary Tree): 除了最后一层之外的其他每一层都被完全填充,并且所有结点都保持向左对齐。
满二叉树(Perfect Binary Tree):除了叶子结点之外的每一个结点都有两个孩子,每一层(当然包含最后一层)都被完全填充。
完满二叉树(Full Binary Tree):除了叶子结点之外的每一个结点都有两个孩子结点。
堆分为大顶堆和小顶堆
- 大顶堆满足 父节点比叶子节点大
K e y [ i ] > = K e y [ 2 i + 1 ] & & k e y [ i ] > = k e y [ 2 i + 2 ] Key[i]>=Key[2i+1] \&\& key[i]>=key[2i+2] Key[i]>=Key[2i+1]&&key[i]>=key[2i+2] - 小顶堆满足 父节点比叶子节点小
K e y [ i ] < = k e y [ 2 i + 1 ] & & K e y [ i ] < = k e y [ 2 i + 2 ] Key[i]<=key[2i+1]\&\&Key[i]<=key[2i+2] Key[i]<=key[2i+1]&&Key[i]<=key[2i+2]
堆满足:
父节点
i
i
i
其子节点分别为
2
i
、
2
i
+
1
2i、2i+1
2i、2i+1
堆排序
整体的时间复杂度为 O(nlogn)
和快排对比:堆排序的数据交换次数多;堆排序数据访问的方式没有快速排序好
思路:
升序用大根堆
降序用小根堆
流程 :
索引为 1 开始(不是 0)
-
建堆:先把data 转换成大根堆
1.1 从最后一个父节点 开始
1.2 如果存在子节点大于父节点,那么值交换
1.3 交换后 查看子节点的子节点值是不是比他大,大的话也交换,直到索引值超出或者 不存在子节点大于父节点
1.4 父节点索引 -1 ,继续步骤1.2 -
排序: 对大根堆进行升序排序
2.1 最后一个节点索引 为high
2.2 把大根堆 根节点(索引为1)和 索引为high值 互换
2.3 high-1 , 做堆排序
重复2部分,直到 high =1
Example
-
建堆 :把 data 初始化为 大根堆:
从最后一个非叶子节点开始 : 节点 4 (8)
因为 13<16 16>8 , 16 和 8 位置交换
往前遍历节点 , 节点3(19)
因为 1<20,20>19 ,19 和 20 位置互换
往前遍历节点 , 节点2(5)
因为 16 > 4 5< 16 ,5 和16 位置互换
因为 13>8 ,13>5 ,13 和5 互换
往前遍历节点 , 节点1(7)
因为 16<20,20>7 , 20和7互换
因为 19>3,19>7 ,19 和7互换
- 排序
建堆结束之后,堆顶元素就是最大元素,我们将其和最后一个元素进行交换,那最大元素就放到了下标为 n 的位置。然后,我们再对前面 n−1 个元素进行堆化,然后将堆顶元素放到下标为 n−1 的位置,重复这个过程,直到堆中剩余一个元素,排序也就完成了。
python 实现
# 大根堆排序
def heap(data,high): # 实现大根堆 完成一次建堆,最大值在堆的顶部(根节点)
last_root = int(high/2)
for t in range(1,last_root+1): # 从最后一个父节点 开始,直到第一个元素(堆排序 序号从1 开始)
i=last_root-t+1
j=2*i
while j<=high:
if(j+1<=high and data[j]<data[j+1]):
j=j+1
if(j<=high and data[i]<data[j]):
temp=data[i]
data[i]=data[j]
data[j]=temp
i=j
j=i*2
else:
break
def heap_sort(data): # 排序
high = len(data)-1
heap(data,high)
length=high+1
for x in range(1,length):
temp=data[1]
data[1]=data[high]
data[high]=temp
heap(data,high-1)
high=high-1
if __name__=='__main__':
data=[0,50, 36, 66, 76, 36, 12, 25, 95] # 堆排序索引从1开始
# data=[0,1,2,3,4,5]
print(data)
heap_sort(data)
print(data)
Reference
https://www.cnblogs.com/Java3y/p/8639937.html
https://www.cnblogs.com/seniusen/p/10023172.html