两种堆排序的比较

来源:互联网 发布:淘宝卖家号怎么关闭 编辑:程序博客网 时间:2024/05/21 07:04

        堆排序是经典的排序问题中,非常重要的一种排序算法,实际上堆排序并没有特别之处,其主要的特点是将数组抽象成一个堆的结构。然后通过堆的二叉树性质进行排序。也正是由于利用了二叉树的性质,所以堆排序的时间复杂度能够达到O(nlogn)。

        下面的总结和比较,主要针对两种堆排序实现进行一个比较。突出两种实现方式对堆排序算法的细微区别和作者对算法的理解,实际上其本质是一样的。第一种是笔者参考机械工业出版社《数据结构》一书中,提出来的算法进行写的代码。两种实现方式中,算法效率更高效的是后者。

#include <iostream> #include <iomanip>#include <cstdlib>using namespace std;void adjust(int array[],int root,int n) //这个调整的函数,效率有一些低,因为它每次都是从最后一个父节点,开始调整堆,实际上其实是不需要每一次都从最后一个父节点开始调整堆的,因为秩序对改变堆的地方进行重新调整堆的操作 {     int child;     int rootkey = array[root];     child = 2 * root;     while(child<=n-1) //这个循环就是直接从堆排序中的二叉树的最后一个父节点,开始调整堆。      {        if((child<n)&&(array[child]<array[child + 1]))//寻找左右子节点中,权值更大的那个子节点         child++;        if(rootkey>array[child])//如果父节点的权值大,跳到下一个循环         break;        else//如果子节点的权值,比父节点大,此时开始交换子节点和父节点的权值         {            array[child/2] = array[child];            child *= 2;        }     }     array[child/2] = rootkey;}void heapsort(int array[],int n){     int i,j;     int temp;     for(i=n/2;i>=0;i--)     adjust(array,i,n);     for(i=n-1;i>=0;i--)     {        temp = array[0];        array[0] = array[i+1];        array[i+1] = temp;         adjust(array,0,i);     }}int main(){    const int NUM=20;    int arr[] = {1,10,11,5,6,15,0,15,16,14,0,8,17,15,7,19,17,1,18,7};    for(int i=0;i<20;i++)    {       cout<<arr[i]<<" ";    }    heapsort(arr,20);    cout<<endl;    for(int i=0;i<20;i++)    {       cout<<arr[i]<<" ";    }    system("PAUSE");    return 0;}

       第二种,是我从博客园上看到的一个博主写的帖子,我觉得很有意思,其对堆排序的理解其实是非常深刻的。下面就对他的方法做一个诠释和总结。这个实现的知识产权属于原作者:http://www.cnblogs.com/dolphin0520/archive/2011/10/06/2199741.html

#include<iostream>#include<cstdlib>using namespace std;void HeapAdjust(int* array,int i,int size)//与上述堆排序实现不同的就体现在这个调整堆的理解上,作者的实现其实只对需要调整的结点进行了堆调整 {     void Swap(int &a,int &b);     int left = 2*i+1;     int right = 2*i+2;     int max = i;     if(i<=size/2)//如果堆排序中的最大堆和最小堆建好了以后,每一次调整堆,如果某一个父节点与其子节点做了调整,实际上接下来的只需要对子节点所在的每一个小的二叉树进行调整,这个步骤比上面的调整堆算法要高效一些      {         if((left<=size)&&(array[left]>array[max]))         {             max = left;         }         if((right<=size)&&(array[right]>array[max]))         {             max = right;         }         if(max != i)//如果当前进行了堆排序的调整,那么接下来做一个递归的调用,对子节点的小二叉树进行堆调整的操作,维持最大堆或者最小堆的性质          {             Swap(array[i],array[max]);             HeapAdjust(array,max,size);         }       }  }void Swap(int &a,int &b){     int temp = a;     a = b;     b = temp;}void BuildHeap(int *array,int size){     for(int i = size/2;i>=0;i--)     HeapAdjust(array,i,size);}void HeapSort(int *array,int size){     void BuildHeap(int *array,int size);     BuildHeap(array,size);     for(int i=size;i>=0;i--)     {         Swap(array[0],array[i]);         HeapAdjust(array,0,i-1);     }   }int main(int argc,char** argv){    int a[100];    int size;    cout<<"Please input the array:";    while(scanf("%d",&size)==1&&size>0)    {        int i;        for(i=0;i<=size-1;i++)        {           cout<<"Please input array["<<i<<"]:";           cin>>a[i];                        }        HeapSort(a,size-1);        cout<<"After Heap Sort,the Array is:"<<endl;        for(i=0;i<=size-1;i++)            cout<<a[i]<<" ";        cout<<endl;    }    return 0;}


原创粉丝点击