您的位置:首页 > 其它

排序算法--堆排序

2006-12-31 18:25 260 查看
要讨论堆排序,首先就要简单的讨论一下堆这种数据结构.

堆排序所用到的二叉堆可以用数组表示出来,而且它可以被看作是一棵完全二叉树.出了树的最后一层,其它层应当是被填满的.

每个节点除了最后一层的叶子节点,从不同的角度观察都具备了不同的角色.假设有一个节点i,我们应当注意它产生的三个不同的角色.

Parent(i) = i / 2;

LeftChild(2i);

RightChild(2i + 1);

堆结构应当满足的性质是:

A[Parent(i)] > A[i]

既子节点最多只能等于父节点,而不能大于父节点.所以当有节点违反这个性质的时候就产生了一种调整的方法,使其符合堆的性质.过程就是查看节点i的LeftChild(i)和RightChild(i)是否大于节点i,如果违反了堆的性质,则把节点i和其较大的子节点交换,然后再递归的查看交换过的节点是否又违反了堆的性质,然后不停的调整,直到堆中所有的节点都没有违反堆的性质.

完成以上的步骤以后,整个数组中的最大值就位于了根节点的位置上,一个大根堆就这样建成了.接下来我们就可以用这个大根堆来进行堆排序了.

堆排序:

算法:

当一个大根堆建好的时候,数组中最大的节点就位于了A[1]的位置,既根节点的位置,我们把这个最大值和堆中的最后一个节点A
交换,并把A
从堆中去掉,将堆的规模减小1.堆排序的一步就完成了.同时因为交换上去的节点再一次的破坏了堆的性质,我们再从新的建立一个大根堆,完成以后,数据数组中的次大元素就位于了根节点的位置,接下来继续对它进行刚才最大元素所经历的操作,照此循环往复,就可以完成堆排序了.完成的时候,数组的第一个节点就是数据中最小的节点,最后一个是最大的节点.

代码:


#include <stdio.h>


#define Parent(i) i / 2


#define Left(i) 2 * i


#define Right(i) (2 * i + 1)




const int MAX = 11;






void Heapify(int *A, int i, int heapSize)




...{


int left, right, parent, largest, temp, done;


done = 0;


largest = -1;


while(Parent(i) <= heapSize && i >= Parent(i))




...{


left = Left(i);


right = Right(i);


parent = Parent(i);


if(left < heapSize && A[left] > A[i])


largest = left;


else


largest = i;


if(right < heapSize && A[right] > A[largest])


largest = right;


if(largest != i)




...{


temp = A[largest];


A[largest] = A[i];


A[i] = temp;


}


i++;


}


}




void buildHeap(int *A, int heapSize)




...{


int i;


for(i = (MAX - 1) / 2; i > 1; i--)


Heapify(A, i, heapSize);


}




void heapSort(int *A)




...{


int i, temp, heapSize;


heapSize = MAX - 1;


buildHeap(A, heapSize);


for(i = MAX - 1; i >= 1; i--)




...{


temp = A[i];


A[i] = A[1];


A[1] = temp;


heapSize -= 1;


Heapify(A, 1, heapSize);


}


}




int main()




...{


int A[MAX];


int i;


int nums = MAX - 1;


printf("Please input %d numbers: ", nums);


for(i = 1; i < MAX; i++)


scanf("%d", &A[i]);


heapSort(A);


for(i = 1; i < MAX; i++)


printf("%d ", A[i]);


return 0;


}

堆排序的时间复杂度的上界是O(nlog2n),现在还没有明确的下界.不过实践中堆排序要比使用Sedgewick增量序列的希尔排序慢.并且因为需要不停的建堆,所以元素较少的时候不推荐用堆排序.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: