您的位置:首页 > 其它

选择排序之堆排序

2015-05-02 11:21 253 查看
#include<stdio.h>
#include<stdlib.h>
void swap(int* data, int i, int j){
int temp;
temp = data[i];
data[i] = data[j];
data[j] = temp;
}
//优美的递归实现堆调整
void adjustBigTopHeap(int* data, int root, int n){
int leftChildIndex = root*2;
int rightChildIndex = leftChildIndex + 1;
//max用来指向(父节点、左孩子节点和右孩子节点三者中)值最大的节点的下标,初始值为父节点的下标
int max = root;
/*仅对以非叶子节点为根的树进行调整,非叶子节点的数组下标,取值范围为[1, n/2]*/
if(1 <= root <= n/2){

//左孩子若存在,且其值大于父节点的值
if(leftChildIndex <= n && data[leftChildIndex] > data[max]){
max = leftChildIndex;

//右孩子若存在,且其值大于左孩子和父节点 (把这个if嵌套在里面是因为堆也是一棵二叉树,只有左孩子存在,右孩子才有可能存在)
if(rightChildIndex <= n && data[rightChildIndex] > data[max])
max = rightChildIndex;
}
//max != root, 意味着左孩子或右孩子大于父节点的值 ,即根为root的二叉树的大顶堆性质被破坏,需重新调整
if(max != root){
swap(data, root, max);
//在其值发生交换后,以左孩子或右孩子为根的二叉树,其大顶堆性质可能被破坏,需对其重新调整
adjustBigTopHeap(data, max, n);
}
/*如果max == root,意味着根为root的二叉树仍满足大顶堆性质,亦无需再向下调整(其子树因为没有发生值交换,故大顶堆性质没有被破坏)*/
}
}

void buildBigTopHeap(int* data, int n){
for(int i = n/2; i >=1; i--)
adjustBigTopHeap(data, i, n);
}

void bigTopHeapSort(int* data, int n){
//构造大顶堆
buildBigTopHeap(data, n);
//进行一系列取顶和调整大顶堆操作,直到堆只有一个元素(为方便计算,根节点的下标从1开始)
for(int i = n; i > 1; i--){
//取顶,并将结果保存在当前趟的最后一位(对应i位)
swap(data, 1, i);
//root是编号为1的二叉树的大顶堆性质被破坏,需重新调整,又因为第i位用来存当前趟已确定的最值,故只需调整下标为1~i - 1的数组元素
adjustBigTopHeap(data, 1, i - 1);
}
}
int main(void){
int* testData;
int n;
printf("请输入数组的大小(n <= 0 时结束):");
while(scanf("%d",&n) == 1 && n > 0){
//因为从数组从下标1开始存数,所有应生成n + 1个int大小的空间,才能存n个数。
testData = (int*)malloc((n + 1)*sizeof(int));
printf("请输入%d个随机的无序整数:",n);
for(int i = 1; i <= n; i++)
scanf("%d", &testData[i]);
bigTopHeapSort(testData, n);
printf("排序后的结果为:");
for(int i = 1; i <= n; i++)
printf("%d ", testData[i]);
printf("\n请输入数组的大小(n <= 0 时结束):");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐