数据结构排序算法之堆排序
来源:互联网 发布:高达00 知乎 编辑:程序博客网 时间:2024/05/18 03:53
关于堆排序的相关知识非常复杂,不懂得可以参考任意一本数据结构教程,本博客只对堆排序框架及代码进行讲解。
堆排序分三个大的步骤:建初堆,堆调整,堆排序(其中最核心的是堆调整)
1建初堆:从数组中的最后一个非叶子节点开始,从下而上倒推(重复调用堆调整函数)
2堆调整:堆调整的前提是已建好了一个堆,但是因为输出,导致需要重新调整堆,首先获得根节点的子节点中的较大的一个节点,然后将其与根节点进行比较看是否需要调整
如果不需要则可以直接结束此次的堆调整函数,因为堆调整的前提是已建好了一个堆,但是因为交换堆顶元素与堆尾元素,导致需要重新调整堆,因此如果某个节点不需要调整,则其子孙节点都不需要调整。
注意:贱初堆是自底向上的过程,而堆调整是自顶向下的过程。
3堆排序:从数组中所有元素开始,将堆顶元素与堆尾元素交换,然后数组的元素个数减一,然后继续调用堆调整函数。
基于以上框架,堆排序的代码如下:
#include<iostream>using namespace std;void sift(int a[],int root,int len)//堆调整函数{int child=2*root;while(child<=len)//注意该函数的参数是从root到len,所以此处必须写={if(child<len&&a[child]<a[child+1])//注意此处必须是child<len,之所以不取=因为child=child+1会溢出{child=child+1; //得到当前根节点的子节点中值较大的节点}if(a[root]<a[child]){swap(a[root],a[child]);root=child;child=2*root;}else{break;//这个地方之所以可以直接break是因为堆调整函数的前提它本身就是堆,只不过交换了之后得重新调整,所以如果当前结点不满足,则它的子孙结点一定都不满足。}}}void cre_heap(int a[],int n){for(int i=n/2;i>=1;i--)//从最后一个非叶子结点开始,自底向上倒推,之所以是从非叶子结点开始。是因为该函数是将当前结点与其子结点比较大小,而叶子结点无子结点{sift(a,i,n);//调整堆函数的参数为,array_name,root,len.}}void heap_sort(int a[],int n){cre_heap(a,n);//堆排序的第一步,建初堆for(int i=n;i>=1;i--){swap(a[1],a[i]);sift(a,1,i-1);}}void main(){int a[10]={0,4,2,1,3,7,6,5,9,8};heap_sort(a,9);for(int i=0;i<10;i++){cout<<a[i]<<' ';}cout<<endl;}程序运行结果如下:
2 0
- 数据结构之排序算法(一)-堆排序
- 数据结构排序算法之堆排序
- 数据结构:排序算法之堆排序和选择排序
- 【数据结构&&算法】堆排序
- [数据结构] 堆排序算法
- 算法与数据结构之堆排序
- 数据结构与算法之六堆排序
- 《数据结构与算法》之堆排序
- 数据结构排序之堆排序
- 数据结构--排序之堆排序
- 数据结构之排序:堆排序
- 数据结构之堆排序
- 数据结构之堆排序
- 数据结构之堆排序
- 数据结构之堆排序
- 数据结构之堆排序
- java数据结构排序之堆排序算法实现
- 排序算法之堆排序
- Html5 Video 移动跨平台实现
- nginx 配置
- c++内存问题整理与智能指针使用
- cocospod后出现Undefined symbols for architecture armv7s\arm64
- LeetCode 59 - Spiral Matrix II
- 数据结构排序算法之堆排序
- 问题集合
- 十大技巧优化Android App性能
- git clone 权限被拒绝
- CALayer与UIView
- LeetCode:Best Time to Buy and Sell Stock with Cooldown
- Ubuntu linux系统下 su:出现: authentication failure的解决办法
- c++ 类成员函数 作回调函数
- 2014年第五届蓝桥杯试题(C/C++本科B组)