堆排序

来源:互联网 发布:在线汇率查询php代码 编辑:程序博客网 时间:2024/06/11 20:54
 


        堆排序一直没有搞的很明白!今天总算搞定了。其实核心在于“堆的调整”。接口形如adjust_heap(*p, int n, int i),一个T类型的,长度为n的数组,将以i为根节点的子树调整为大顶堆或者小顶堆。原理可以这么想:根节点T[i]有左孩子T[2*i+1]和右孩子T[2*i+2],假如左孩子已经是一个大顶堆,右孩子也是大顶堆,而且:

    T[i] > T[2*i+1]

    T[i] > T[2*i+2]

那么,根据堆的定义,T[i]就是一个大顶堆了。

 

    堆排序首先定义了这么一个“堆的调整”操作,随后的算法都是基于此的。堆以数组存储,a[N],最后一个元素为a[N-1],其父节点为a[(N-1-1)/2],将a[(N-1-1)/2]调整为大顶堆,然后向前走,将a[(N-1-1)/2-1]、a[(N-1-1)/2-2]、。。。a[2]、a[1]、a[0]调整为大顶堆。最后整个数组是一个大顶堆。

    随后删除元素。删除堆顶,将a[0]与最后一个元素a[N-1]交换,此时a[N-1]为最大值,随后对a[0]至a[N-2]范围的元素做“堆的调整”操作,调整为堆后,又删除堆顶,得到第二大的元素。。。。最后数组呈现递增排列。

    所谓“堆的调整”就是,左孩子和右孩子都已经是堆了,根节点是新来的,此时需要自上而下调整一遍。

复杂度:一次堆的调整为log(n),建堆需要n Log(n)。删除元素为O(1),重新调整N次,复杂度也是n*log(n),最终复杂度为n*log(n)。

 

 

// 堆排序// 堆的调整、建堆、删除#include <stdio.h>#include <stdlib.h>template<typename T>int is_heap(T *tp, int nLen);template<typename T>void adjust_heap(T *tp, int nLen, int pos);template<typename T>void make_heap(T *tp, int nLen);template<typename T>void heap_sort(T *tp, int nLen);const int N=20;int main(){int ap[N];int i;for (i=0;i<N;i++){ap[i]=rand()%100;printf("%d ", ap[i]);}printf("\n");heap_sort(ap,N);printf("排序后:\n");for (i=0;i<N;i++){printf("%d ", ap[i]);}printf("\n");return 0;}//----------------------------------------// 交换元素template<typename T>void _swap(T &a, T&b){T tmp;tmp=a;a=b;b=tmp;}// 堆的调整template<typename T>void adjust_heap(T *tp, int nLen, int pos){int i=pos;int j=2*i+1;for ( ;j<nLen; ){if (j+1<nLen && tp[j+1]<tp[j])j++;if (tp[i] < tp[j]){break;}_swap(tp[i], tp[j]);i=j;j=2*j+1;}}// 建堆template<typename T>void make_heap(T *tp, int nLen){int i;for (i=(nLen-1-1)/2; i>=0; i--){adjust_heap(tp, nLen, i);}if (is_heap(tp,nLen)){printf("IS a HEAP\n");}else{printf("NOT a HEAP\n");}}// 排序template<typename T>void heap_sort(T *tp, int nLen){make_heap(tp, nLen);int i;for (i=nLen-1; i>=1; i--){_swap(tp[0], tp[i]);adjust_heap(tp, i, 0);}}// 判断是否为堆template<typename T>int is_heap(T *tp, int nLen){int i;for (i=0; 2*i+1<nLen; i++){if (tp[i]>tp[2*i+1])return 0;if (2*i+2<nLen && tp[i]>tp[2*i+2])return 0;}return 1;}


 

 

ref:

http://blog.csdn.net/fly_yr/article/details/8550701

http://blog.sina.com.cn/s/blog_5115d58c0100vr26.html

 

原创粉丝点击