堆排序
来源:互联网 发布:广告联盟知乎 编辑:程序博客网 时间:2024/05/17 22:11
堆排序
堆的基础知识我们已经在《堆的基础知识》:http://blog.csdn.net/ii1245712564/article/details/45505799里面介绍过了,这次我们将介绍堆的用途之一:堆排序
在诸多的排序算法里面里面,堆排序算是比较快速的了,排序时间消耗为:
我们这里给出一个堆排序的基本思路:
这里我们就按照上面的流程图思路来对每一步骤进行构建
建堆
加入给定我们一个数组
还记得我们在文章《堆的基础知识》里面提到过一个维护堆性质的函数MAX-HEAPIFY(A,i)
吗?MAX-HEAPIFY(A,i)
这个函数是在节点i的左子树和右子树均满足最大堆的性质下进行的。
但是我们在数组PARENT(i)
是一定小于i
的,所以在我们用MAX-HEAPIFY(A,i)
维护节点i
的性质的时候,其子树是一定具有最大堆的性质的,因为其子树LEFTCHILD(i)
和RIGHTCHILD(i)
的最大堆性质是早于其父节点i
构建的,且其运行时间为
下面我们给出建堆的伪代码:
BUILD-MAX-HEAP(A) for i = A.heapSize/2 downto 1 MAX-HEAPIFY(A,i)
于是我们就可以将数组
好了,在我们构建出最大堆以后,我们需要做的就是来进行堆排序的核心操作啦!
堆排序操作
给定我们一个最大堆1
进行堆性质的维护,之后堆顶元素就成了剩下元素里面最大的,再次提出该元素,重复上面的动作,直到堆只剩下一个元素即可,这个就是堆排序的核心思想了。
为了怎么空间的可重用性,我们不妨将堆顶元素和堆尾部的元素交换,然后让堆大小减小一,当整个操作完毕后,数组
下面我们用伪代码实现:
HEAPSORT(A) BUILD-MAX-HEAP(A) while A.heapSize > 1 exchange(A,A.heapSize,1) A.heapSize = A.heapSize-1 MAX-HEAPIFY(A,1)
代码实现
/************************************************** @Filename: heapSort.cc* @Author: qeesung* @Email: qeesung@qq.com* @DateTime: 2015-05-06 10:32:10* @Version: 1.0* @Description: 堆排序**************************************************/#include <iostream>using namespace std;// 二叉树的基本操作#define PARENT(i) ((i)>>1)#define LEFTCHILD(i) ((i)<<1)#define RIGHTCHILD(i) (((i)<<1)+1)void printArray(int * array);/** * 交换数组两个位置的元素 * @param array 数组 * @param pos1 位置1 * @param pos2 位置2 */void exchange(int * array , int pos1 , int pos2){ if(array == NULL) return; int temp = array[pos1]; array[pos1] = array[pos2]; array[pos2] = temp;}/** * 维护最大堆的性质 * @param array 传入的堆数组,注意此数组是从位置1开始,位置0存放堆的大小 * @param pos 需要更新的位置 */void maxHeapify(int * array , int pos){ if(array == NULL) return; if(pos > array[0])// 超出堆的大小 return; int leftChild = LEFTCHILD(pos); int rightChild = RIGHTCHILD(pos); // 找到最大的那个 int maxPos = pos; if(leftChild <= array[0] && array[leftChild] > array[pos] ) maxPos = leftChild; if(rightChild <= array[0] && array[rightChild] > array[maxPos]) maxPos = rightChild; // 交换父节点与子节点 if(maxPos != pos) { exchange(array , maxPos , pos); maxHeapify(array , maxPos); }}/** * 堆排序 * @param array 传入需要排序的数组,注意此数组是从位置1开始,位置0存放数组数组元素的个数 */void heapSort(int * array){ if(array == NULL) return; // 首先构建最大堆 for(int k = array[0]/2 ; k >=1 ; --k) { maxHeapify(array , k); } int arraySize = array[0]; //下面开始每次都取出堆里面堆顶位置的元素,再次进行堆性质维护 for(int k = array[0] ; k >=2 ; --k) { exchange(array , 1, k); array[0] -= 1; maxHeapify(array , 1); } array[0] = arraySize;}void printArray(int * array){ if(array == NULL) return; int arraySize = array[0]; for(int k = 1 ; k <= arraySize ; ++k) { cout<<array[k]<<"\t"; } cout<<endl;}int main(int argc, char const *argv[]){ int array[]={0,4,1,3,2,16,9,10,14,8,7}; array[0] = sizeof(array)/sizeof(int) - 1; cout<<"before sort:"<<endl; printArray(array); heapSort(array); cout<<"after sort:"<<endl; printArray(array); return 0;}
运行结果为:
before sort:
4 1 3 2 16 9 10 14 8 7
after sort:
1 2 3 4 7 8 9 10 14 16
- 堆及堆排序
- 堆/堆排序特点
- 【二叉堆、堆排序】
- 二叉堆 & 堆排序
- 二叉堆 & 堆排序
- 堆与堆排序
- 堆与堆排序
- 堆与堆排序
- 堆与堆排序
- 堆与堆排序
- 堆与堆排序
- 堆和堆排序
- 堆排序(最大堆)
- 堆和堆排序
- 堆和堆排序
- 堆及堆排序
- 堆和堆排序
- 堆与堆排序
- [好程序员训练营]-----java基础笔记之设计模式之单例模式和工厂模式
- 第36课第二题
- asp.net 自定义组合控件必须继承INamingContainer接口原因分析
- DTE Linux、SELinux与SEAndroid之间的对比分析
- FTP学习的一些笔记
- 堆排序
- 【算法设计-链表】单链表与双向循环链表
- 使用Angular提交表单
- Outlook 2013 pst/ost邮件数据文件迁移实现
- 使用Java VisualVM监控远程JVM
- Android UI设计: 仿QQ好友列表分组悬停,自定义Header,下拉刷新结合Demo
- XML基础见解
- selenium webdriver学习(一)---如何处理alert、confirm、prompt对话框
- 再识PCI:一个PCI驱动实例