堆排序

来源:互联网 发布:提高环境监测数据质量 编辑:程序博客网 时间:2024/05/16 09:40

1.什么是堆?

堆的定义:堆是一棵完全二叉树按照顺序存储方式得到的一个数组,且满足父节点的值大于左右孩子结点的值。(大根堆)

2.维护大根堆的性质

假定:以数组A中第i个元素的左孩子、右孩子为跟结点的二叉树满足大根堆的要求,若A[i]小于其孩子的值,则违背大根堆的要求。

解决方法: 
(1)找出A[i]、其左孩子、右孩子的最大值,下标为largest。 
(2)如果largest == i,表明结点i满足大根堆要求,结束; 
如果largest != i,表明结点i不满足大根堆要求,交换A[largest]与A[i],这样largest位置上的值是A[i],有可能以largest为根的结点违背大根堆的要求,这样的话,继续递归向下调整largest结点。

代码如下:

//维护大根堆的性质,从第i个元素向下调整//其假定是,以当前结点i的左孩子、右孩子为根结点的二叉树是大根堆。//len表示最后一个元素的下标。void maxHeapify(int A[],int len, int i){//找到当前节点i,左孩子、右孩子 的最大值的下标int left = i * 2;int right = i * 2 + 1;int largest = i;if (left <= len && A[left] > A[i])largest = left;if (right <= len && A[right] > A[largest])largest = right;//如果A[i]最大,则结束,否则交换A[largest]与A[i],然后递归if (i != largest){int temp = A[i];A[i] = A[largest];A[largest] = temp;maxHeapify(A,len,largest);}}

3. 建立大根堆

用自底向上的方法利用过程maxHeapify,把数组转化为大根堆。数组的len/2之后的元素为叶结点,每个叶结点看作是只包含一个元素的堆。这样的话对其余结点依次调用maxHeapify便可。 
代码如下:

//自底向上建堆,叶子结点已经是一个堆了,故从i=len/2开始调整。void buildheap(int A[],int len){for(int i = len/2; i >= 1; i--){maxHeapify(A,len,i);}}

4.堆排序

堆排序:建好堆以后,交换第一个和最后一个元素,则最后的是最大数。如果从堆中去掉最后一个元素,使size减1,重新调整大根堆maxHeapify(A[],len, 1),再交换第一个和最后一个元素,以此类推,直到堆的size为1,结束。 
代码如下:

void heapsort(int A[], int len){buildheap(A,len);    for(int i = len; i>1; i--){  //交换换第一个和最后一个元素,size减1  int temp = A[1]; A[1] = A[i];A[i]= temp;  //调整大根堆  maxHeapify(A,i,1);}}


测试代码如下:

#include <iostream>using namespace std;int main(){int A[] = {0,3,2,9,7,1};//len表示最后一个元素的下标。heapsort(A,5);for(int i = 1; i<6; i++)cout<<A[i]<<" ";return 0;}


0 0
原创粉丝点击