排序算法中对堆排序的解析

来源:互联网 发布:腾讯汽车招聘php 编辑:程序博客网 时间:2024/05/21 03:25

堆排序的算法是紧接希尔排序,它的原理就是把一个待排序的序列先创建成一个二叉树,这个二叉树具有的性质是:每一个节点都大于它的孩子节点,即为:大顶堆,反之即为小顶堆。

要实现这样的二叉树,我们从下往上,从左往右将每个非叶子节点作为根节点,将其和它的叶子节点作比较,实施交换,将最大的节点上升为非叶子节点。所以我们先要找到二叉树的根节点,这里可以用 n/2  来表示最后面非叶子节点的坐标。在这个循环操作之后,最大的节点上升为了整颗二叉树的根节点。也就是说在整个序列中第一个数就是最大的数,注意:最后一个数不一定是最小的数。

代码实现如下:

先创建一个结构体:

#define MAXSIZE 100typedef struct{    int r[MAXSIZE];    int length;}

在程序中我们是从下标为  1 来开始存储和遍历数的。

void createHeapSort(SqList *L){    int i;    for(i = L->length/2; i >0; i--){        heapAdjust(L,i,L->length);    }}

这里我们从最后一个非叶子节点开始向上走,没走一次都将子树中最大的节点上升为非叶子节点

void heapAdjust(SqList *L, int s, int m){    int j, temp;    temp = L->r[s];    for(j = 2*s; j <= m; j *= 2){if(j < m && L->r[j] < L->r[j+1]){    ++j;}if(temp >= L->r[j]){    break;}L->r[s] = L->r[j];s = j;    }    L->r[s] = temp;}

这里的作用就是创建一个二叉树,将这个树中最大的节点上升为整棵树的根节点。
接下来就可以进行排序了:

void heapSort(SqList *L){    int i;    for(i = L->length; i > 1; i--){swap(L,i,1);heapAdjust(L,1,i-1);    }}

这里将堆顶元素和最后的一个元素做交换,这样一来整个序列中最开始的数即使整个序列最大的值。接着就可以将最大的数排除,重新创建一个树。以此循环。就可以不断地将最大的数升上来,这里有点像冒泡。