堆排序

来源:互联网 发布:cgi加载java class 编辑:程序博客网 时间:2024/06/06 15:20


将完全二叉树中的结点对应到一维数组中。

定义调整操作:
条件:以左右结点为根节点的完全二叉树都是堆
1.以当前元素和其左、右子树的根结点进行比较(此时,左、右子树均为堆),并与值较小的结点进行交换;
2.重复1,继续调整被交换过的子树,直到叶结点或无法进行交换为止。
称这个调整过程为"筛选"。

算法过程:

1.从完全二叉树的最后一个非终端结点n/2开始,反复调用筛选过程,直到第一个结点,则得到一个堆。

2.将结点n与结点1互换,对剩余的1~n-1个结点进行筛选操作,重新调整为一个小顶堆,如此反复操作,直至只剩下结点1。


英文解释:

The heapsort algorithm can be divided into two parts.

In the first step, a heap is built out of the data. The heap is often placed in an array with the layout of a completebinary tree.  Each array index represents a node; the index of the node's parent, left child branch, or right child branch are simple expressions.ifi is the index of the current node, then the index of the left child and right child are 2 multiply i and 2 multiply i add 1.

In the second step, a sorted array is created by repeatedly removing the largest element from the root of the heap, and inserting it into the array. The heap is updated after each removal to maintain the heap. Once all objects have been removed from the heap, the result is a sorted array.


#include<iostream>using namespace std;int h[1010];int n;void HeapAdjust(int s,int m){    for(int i=2*s;i<=m;i=i*2)//左结点序号<=m才有下一层    {        if(i<m&&h[i+1]<h[i])//i<m才有右节点            i++;        if(h[s]<=h[i])//在正确位置            break;        else        {            swap(h[s],h[i]);            s=i;        }    }}void HeapSort(){    for(int i=n/2;i>=1;i--)//初始建立小顶堆        HeapAdjust(i,n);    for(int i=n;i>=2;i--)//将最小值h[1]与h[i]交换位置后,对剩余1~i-1个元素建堆    {        swap(h[i],h[1]);        HeapAdjust(1,i-1);    }}int main(){    cin>>n;    for(int i=1;i<=n;i++)        cin>>h[i];    HeapSort();    for(int i=n;i>=1;i--)        cout<<h[i]<<" ";    cout<<endl;    return 0;}

时间复杂度分析:

对深度为 k 的堆,“筛选”所需进行的关键字比较的次数至多为2(k-1);

对 n 个关键字,建成深度为所需进行的关键字比较的次数至多 4n;

调整“堆顶” n-1 次,总共进行的关键 字比较的次数不超过


原创粉丝点击