网站首页 > 基础教程 正文
简介
堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。
堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。堆排序可以说是一种利用堆的概念来排序的选择排序。
特点
- 堆:一种特殊的完全二叉树结构
- 大根堆:一棵完全二叉树,满足任一节点都比其孩子节点大
- 小根堆:一棵完全二叉树,满足任一节点都比其孩子节点小
堆排序节点访问
在这里我们借用wiki的定义来说明:
通常堆是通过一维数组来实现的。在阵列起始位置为0的情况中
父节点i的左子节点在位置:(2*i+1);
父节点i的右子节点在位置:(2*i+2);
子节点i的父节点在位置:(i-1)//2;
执行步骤
- 构建堆:将待排序序列构建成一个堆 H[0……n-1],从最后一个非叶子结点开始,从左至右,从下至上进行调整。根据升序或降序需求选择大顶堆或小顶堆;
- 此时的堆顶元素,为最大或者最小元素;
- 把堆顶元素和堆尾元素互换,调整堆,重新使堆有序;
- 此时堆顶元素为第二大元素;
- 重复以上步骤,直到堆变空。
动图演示
实例代码
####
# 今日头条:技术好奇心
####
# 构建维护堆
def heapify(arr, n, i):
# 最大位置
largest = i
# left = 2*i + 1
l = 2 * i + 1
# right = 2*i + 2
r = 2 * i + 2
# 比较父节点与左孩子大小
if l < n and arr[i] < arr[l]:
largest = l
# 比较右孩子与目前的大节点值大小
# (目前可能是父亲也可能是左孩子)
if r < n and arr[largest] < arr[r]:
largest = r
# 检查上面步骤得出的最大值是否是最初上面定义的父节点
# 如果不是,则进行交换和递归
if largest != i:
# 交换
arr[i], arr[largest] = arr[largest], arr[i]
# 递归对子树作出调整
heapify(arr, n, largest)
# 堆排序
def heap_sort(arr):
# 数组长度
n = len(arr)
# 构建大顶堆,由下往上构建所以用-1
for i in range(n, -1, -1):
heapify(arr, n, i)
print('--------- 构建之后的数组内容 ----------')
print(arr)
# 一个个交换元素
for i in range(n - 1, 0, -1):
# 交换
arr[i], arr[0] = arr[0], arr[i]
# 维护交换后的堆
heapify(arr, i, 0)
if __name__ == "__main__":
print('今日头条:技术好奇心')
print('----------- 排序前数组内容 -----------------')
arr = [2, 7, 26, 25, 19, 17, 1, 90, 3, 36]
print(arr)
heap_sort(arr)
print('------------ 排序后的结果 ------------------')
print(arr)
运行结果:
今日头条:技术好奇心
----------- 排序前数组内容 -----------------
[2, 7, 26, 25, 19, 17, 1, 90, 3, 36]
------------ 排序后的结果 ------------------
[1, 2, 3, 7, 17, 19, 25, 26, 36, 90]
相关文章
- 上一篇: Python版排序算法总结
- 下一篇: 关于面试常见问题:Redis有哪些数据结构?
猜你喜欢
- 2024-11-22 Python版排序算法总结
- 2024-11-22 python冷门操作-11.list排序干货
- 2024-11-22 Python 排序了解一下
- 2024-11-22 Python实现冒泡排序
- 2024-11-22 Python 快速排序:高效算法一探究竟
- 2024-11-22 Python实现快速排序
- 2024-11-22 python对象自定义排序你知道吗
- 2024-11-22 Python应用——自定义排序全套方案
- 2024-11-22 Python函数知识整理
- 2024-11-22 冒泡排序(python版)
- 最近发表
- 标签列表
-
- gitpush (61)
- pythonif (68)
- location.href (57)
- tail-f (57)
- pythonifelse (59)
- deletesql (62)
- c++模板 (62)
- css3动画 (57)
- c#event (59)
- linuxgzip (68)
- 字符串连接 (73)
- nginx配置文件详解 (61)
- html标签 (69)
- c++初始化列表 (64)
- exec命令 (59)
- canvasfilltext (58)
- mysqlinnodbmyisam区别 (63)
- arraylistadd (66)
- node教程 (59)
- console.table (62)
- c++time_t (58)
- phpcookie (58)
- mysqldatesub函数 (63)
- window10java环境变量设置 (66)
- c++虚函数和纯虚函数的区别 (66)