排序算法(3)——堆排序简介与简单实现

提要:对于堆排序,我想这是我们面试以及在大数据处理时代必不可少的经典算法。其实可以简单在此做个总结:对排序的核心其实是二叉树,它的算法思想则是来源于我们后面会提到的选择排序,这也是它相对于直接排序有更好地时间节约的原因。一般来说,它的时间复杂度与quicksort近似,都为O(nlgn),而且它也是一种不稳定排序,易受原序列特征影响。
以下(1)中说明来自百度和clam_clam的CSDN博客。
1991年计算机先驱奖获得者、斯坦福大学计算机科学系教授罗伯特·弗洛伊德(Robert W.Floyd)和威廉姆斯(J.Williams)在1964年共同发明了著名的堆排序算法( Heap Sort )
 
1.堆排序是利用堆的特性对记录序列进行排序的一种排序方法。
好的那么堆得特性是什么呢?
堆得定义:
堆是满足下列性质的数列{r1, r2, …,rn}:

 
如下图最开始是一个小顶堆。当把97和13 交换后不是堆了,所以我们要调整根节点使之成为堆即筛选。(注意:是自堆顶到叶子的筛选过程,应该刚开始是堆由于把堆顶给换了,罪魁祸首是堆顶,其它小范围还是堆,所以是从堆顶开始)。

这其中还要注意一点。97 与13 交换后应该跟27 比较
因为是小顶堆,所以在97 的子节点里选择小者。如果把38放上去。38成了27的父节点比27大就不是小顶堆了。如果换成大顶堆就要比较把大的数据放上去。
所以程序里交换时要先要比较一下。

ok,下面是我实现的一个简单对排序算法,包括自底而上的建堆,和自上而下的小顶化。

#include <iostream>
#include <stdio.h>

using namespace std;

template <class T>
void Min_Heaped(T* arr,int heapsize,int iRoot){              //数据的最小堆化,即从根iroot开始和他的孩子做堆化

    int lchild=2*iRoot;
    int temp=arr[iRoot];
    int bHeap=1;
    while(lchild<heapsize && bHeap)
    {
        if (arr[lchild]>arr[lchild+1] && (lchild+1)<=heapsize)//若有分枝小,则指针移到有分枝堆化,否则直接对话指针所在的左面。
            lchild++;
            if (temp<arr[lchild])                              //若当前根已是最小,则不做任何操作
                bHeap=0;
            else                                               //否则将这个最新的小值节点升到根位置
            {
                arr[iRoot]=arr[lchild];
                iRoot=lchild;                                  //升完根后,要向下继续堆化下一级,直至底部
                lchild=2*iRoot;
            }    
    }
    arr[iRoot]=temp;                                           //将开始的根值放在合适的位置

}

template <class Ti>
void Build_MinHeap(Ti *arr,int heaplength){
    int i;
    for (i=heaplength/2;i>=1;i--)
    {
        Min_Heaped(arr,heaplength,i);             //从i个记录开始进行筛选建堆
    }
}

template <class T0>
void HeapSorted(T0 *a,int len){
    int ie,tempe;
    Build_MinHeap(a,len);//建最小堆
    for(ie=len;ie>1;ie--){
        cout<<"The top element of heap is:";
        cout<<a[1]<<endl;
        tempe=a[1];
        a[1]=a[ie];
        a[ie]=tempe;//将出堆最小元素放入临时队列中,从最后一位向前装
        Min_Heaped(a,ie-1,1);
        
    }
}

int main(){

    int a[100];
    int i,length;
    cout<<"Input arry number:";
    cin>>length;

    for(i=1;i<=length;i++)
        cin>>a[i];
    cout<<endl;

    Build_MinHeap(a,length);

    cout<<"The heap elements as follows:"<<endl;

    for(i=1;i<=length;i++)
        cout<<a[i]<<" ";
    cout<<endl;

    cout<<"Heap sorted as follows: "<<endl;
    HeapSorted(a,5);//此中存放的是由大到小的顺序

    system("pause");
    return 0;
}

posted @ 2013-04-10 22:14  追风筝的小蜗牛  阅读(111)  评论(0)    收藏  举报