堆排序

来源:互联网 发布:怎么恢复手机里的数据 编辑:程序博客网 时间:2024/04/29 22:34

原理:

将无序序列看成一个完全二叉树,根结点即list[0]。将二叉树构造成最大(最小堆),然后将首元素(即最大(最小)元素)与无序序列的末尾元素交换,将剩下的无序序列调整为最大(最小)堆,交换首元素与末尾元素,依次类推,直至无序序列元素剩余一个元素。

对排序的一般实现:

void swap(int *a,int *b){int temp;temp = *a;*a = *b;*b = temp;}void heapify(int list[],int root,int n){/* list subscripts start from 0. */int child;int temp;temp = list[root];child = 2 * root + 1;while(child<=n){if(child<n && list[child]<list[child+1])child++;if(temp>list[child])break;else{list[(child-1)/2] = list[child];child = 2 * child + 1;}}list[(child-1)/2] = temp;}void heapSort(int list[],int n){/* n the the max subscript of elements in list. */int i,j;for(i=(n-1)/2;i>=0;i--)heapify(list,i,n);for(j=n-1;j>=0;j--){swap(&list[j+1],&list[0]);heapify(list,0,j);}}
测试数据如下显示:

76  59  67  85  16  54  47  50  68  37  85  76  67  68  37  54  47  50  59  16  76  68  67  59  37  54  47  50  16  85  68  59  67  50  37  54  47  16  76  85  67  59  54  50  37  16  47  68  76  85  59  50  54  47  37  16  67  68  76  85  54  50  16  47  37  59  67  68  76  85  50  47  16  37  54  59  67  68  76  85  47  37  16  50  54  59  67  68  76  85  37  16  47  50  54  59  67  68  76  85  16  37  47  50  54  59  67  68  76  85  

由于无序序列的首元素下标为0,对于任意结点i,其左右儿子结点的下标为2*i+1和2*i+2,对于任意结点child,其父结点的下标为(child-1)/2(正如上述代码实现)。若首元素的下标从1开始,那么对于任意结点i,其左右儿子结点下标为2*i和2*i+1,对于任意结点child,其父结点的下标为child/2。

0 0
原创粉丝点击