(1)用大根堆排序的基本思想
① 先将初始文件R[1..n]建成一个大根堆,此堆为初始的无序区
② 再将关键字最大的记录R[1](即堆顶)和无序区的最后一个记录R[n]交换,由此得到新的无序区R[1..n-1]和有序区R[n],且满足R[1..n-1].keys≤R[n].key
③ 由于交换后新的根R[1]可能违反堆性质,故应将当前无序区R[1..n-1]调整为堆。然后再次将R[1..n-1]中关键字最大的记录R[1]和该区间的最后一个记录R[n-1]交换,由此得到新的无序区R[1..n-2]和有序区R[n-1..n],且仍满足关系R[1..n-2].keys≤R[n-1..n].keys,同样要将R[1..n-2]调整为堆。
……
直到无序区只有一个元素为止。
(2)大根堆排序算法的基本操作:
① 初始化操作:将R[1..n]构造为初始堆;
② 每一趟排序的基本操作:将当前无序区的堆顶记录R[1]和该区间的最后一个记录交换,然后将新的无序区调整为堆(亦称重建堆)。
注意:
①只需做n-1趟排序,选出较大的n-1个关键字即可以使得文件递增有序。
②用小根堆排序与利用大根堆类似,只不过其排序结果是递减有序的。堆排序和直接选择排序相反:在任何时刻,堆排序中无序区总是在有序区之前,且有序区是在原向量的尾部由后往前逐步扩大至整个向量为止。
(3)堆排序的算法:
void HeapSort(SeqIAst R)
{ //对R[1..n]进行堆排序,不妨用R[0]做暂存单元
int i;
BuildHeap(R); //将R[1-n]建成初始堆
for(i=n;i>1;i--){ //对当前无序区R[1..i]进行堆排序,共做n-1趟。
R[0]=R[1];R[1]=R[i];R[i]=R[0]; //将堆顶和堆中最后一个记录交换
Heapify(R,1,i-1); //将R[1..i-1]重新调整为堆,仅有R[1]可能违反堆性质
} //endfor
} //HeapSort
Flash演示动画:
Flash Player文件Java实现:
02
03 /**
04 * @author yovn
05 *
06 */
07 public class HeapSorter<E extends Comparable<E>> extends Sorter<E> {
08
09 /* (non-Javadoc)
10 * @see algorithms.Sorter#sort(E[], int, int)
11 */
12 @Override
13 public void sort(E[] array, int from, int len) {
14 build_heap(array,from,len);
15
16 for(int i=0;i<len;i++)
17 {
18 //swap max value to the (len-i)-th position
19 swap(array,from,from+len-1-i);
20 shift_down(array,from,len-1-i,0);//always shiftDown from 0
21 }
22 }
23
24 private final void build_heap(E[] array, int from, int len) {
25 int pos=(len-1)/2;//we start from (len-1)/2, because branch's node +1=leaf's node, and all leaf node is already a heap
26 for(int i=pos;i>=0;i--)
27 {
28 shift_down(array,from,len,i);
29 }
30
31 }
32
33 private final void shift_down(E[] array,int from, int len, int pos)
34 {
35
36 E tmp=array[from+pos];
37 int index=pos*2+1;//use left child
38 while(index<len)//until no child
39 {
40 if(index+1<len&&array[from+index].compareTo(array[from+index+1])<0)//right child is bigger
41 {
42 index+=1;//switch to right child
43 }
44 if(tmp.compareTo(array[from+index])<0)
45 {
46 array[from+pos]=array[from+index];
47 pos=index;
48 index=pos*2+1;
49
50 }
51 else
52 {
53 break;
54 }
55
56 }
57 array[from+pos]=tmp;
58
59 }
60
61
62 }
C语言实现:
02 #define Right(i) (((i) << 1) + 1)
03 void heapsort(int a[], int heapsize);
04 void maxheapify(int a[], int i, int heapsize);
05 void swap(int *x, int *y);
06 main(){
07 int ts[5]={21,25,11,24,77};
08 heapsort(ts,n1);
09 }
10 void heapsort(int a[], int heapsize)
11 {
12 int i;
13
14 for (i = heapsize / 2; i >= 1; i--)
15 maxheapify(a, i, heapsize);
16
17 for (i = heapsize; i >= 2; i--)
18 {
19 swap(&a[1], &a[i]);
20 heapsize--;
21 maxheapify(a, 1, heapsize);
22 }
23 }
24 void maxheapify(int a[], int i, int heapsize)
25 {
26 int largest, left, right;
27
28 left = Left(i);
29 right = Right(i);
30
31 if (left <= heapsize && a[left] > a[i])
32 largest = left;
33 else
34 largest = i;
35 if (right <= heapsize && a[right] > a[largest])
36 largest = right;
37
38 if (largest != i)
39 {
40 swap(&a[i], &a[largest]);
41 maxheapify(a, largest, heapsize);
42 }
43
44 return;
45 }
46 void swap(int *x, int *y)
47 {
48 int temp;
49
50 temp = *x;
51 *x = *y;
52 *y = temp;
53 }


我们都是爱的囚徒! ~Prisoner of love~
童年的点滴回忆……

