数据结构和算法 堆排序 (图解堆调整)
2020-06-24 04:27
363 查看
什么是堆?
堆:是一种特殊的序列 并且 将该序列想象为 完全二叉树
元素满足:
- (ki <= k2i && ki <= k2i+1) 每个结点一定比它的左右孩子小 这种堆称为 最小化堆(小堆) (树根是最小的)
- (ki >= k2i && ki >= k2i+1) 每个点一定比它的左右孩子大 这种堆称为 最大化堆(大堆) (树根是最大的)
堆排序(以最大化堆为例)
堆调整:排序之前需要将序列调整为 堆 (不满足时 与 左右孩子中较大的那一个进行交换) 从n/2向下取整个点开始由后向前调整直到满足堆条件为止。
排序:
- 从堆顶取出最大元素 ,堆顶元素与堆的最后一个元素交换位置 (往后就不用考虑当前最后一个元素)。
- 对剩余的元素进行调整 , 调整选择剩下元素中的最大元素 (根与左右孩子中较大的那个进行交换直到满足条件为止)即 对根进行堆调整。
- 重复以上过程 直到序列有序为止 (大堆升序)。
例子 (堆调整过程)
初始序列为:5 4 8 0 9 3 2 6 7 1
1.画出该序列完全二叉树
2.找到n/2向下取整的点 本例为 (9)从后往前逐个调整
-
0 < 6 同时 0 < 7 因为 7 > 6 故 0 与 7 交换 ;满足条件 。
8满足条件 继续 4 < 7 同时 4 < 9 因为 9 > 7 故 4 与 9 交换 ;满足条件。
-
5 < 9 同时 5 < 8 因为 9 > 8 故 5 与 9 交换 ;此时 5 < 7 不满足 5与7 交换 ;此时 5 <
6 不满足 5与6 交换;满足条件。 -
堆排序
参考上述排序过程。
代码
#include <iostream> #include <algorithm> #include <cstdio> #include <cstring> typedef long long ll; using namespace std; const int N = 1010; int n; int a[N]; void mheap(int a[],int x,int m) { int temp; while((2*x <= m && a[x] < a[2*x]) || (2*x+1 <= m && a[x] < a[2*x+1])) // 小于左右孩子 并且 防止越界 { temp = a[2*x] >= a[2*x+1]||2*x == m ? 2*x:2*x+1; // 比较左右孩子取较大的那个,也可能存在只有左孩子 swap(a[x],a[temp]); x = temp; } } void heapsort(int a[],int len) { for(int i = len/2;i >= 1;i--) mheap(a,i,len); //对n/2向下取整由后往前调整 for(int j = len;j >= 2;j--) { swap(a[1],a[j]); mheap(a,1,j - 1); //对根节点调整 } } int main() { ios::sync_with_stdio(0),cin.tie(0); cin >> n; for(int i = 1;i <= n;i++) cin >> a[i]; heapsort(a,n); for(int i = 1;i <= n;i++) cout << a[i] <<' '; return 0; }
相关文章推荐
- 第16周SHH数据结构-【项目1-验证算法(6)堆排序 】
- 数据结构和算法分析之排序算法--选择排序(堆排序)
- 一步步学习数据结构和算法之堆排序效率分析及java实现
- 《数据结构与算法——C语言描述》答案 3.15 自调整表的实现(链表法)
- 【算法与数据结构】冒泡、插入、归并、堆排序、快速排序的Java实现代码
- 浅谈算法和数据结构: 五 优先级队列与堆排序
- Python天天美味(32) - python数据结构与算法之堆排序
- 【算法与数据结构】图说堆排序
- 【算法与数据结构】图说堆排序
- 堆排序,插入,删除,调整算法(大顶堆)
- 【数据结构】浅谈算法和数据结构:优先队列和堆排序
- 【数据结构和算法】排序算法之二:选择排序和堆排序
- 【数据结构和算法】排序算法之二:选择排序和堆排序
- 经典算法(16)堆排序图解及其代码实现
- 算法设计和数据结构学习堆排序
- 经典算法和数据结构(一) 优先级队列与堆排序
- 算法与数据结构之堆排序
- python算法和数据结构笔记--汉诺塔问题超详细递归过程图解(堆栈数据结构)
- 【数据结构&&算法系列】堆排序简单介绍及其实现