【算法分析】排序算法:堆排序

来源:互联网 发布:数据调研公司排名 编辑:程序博客网 时间:2024/05/16 14:34

        堆排序是一种就地排序方法(请参看《算法导论》一书),在代码中,我用递归的方法写了一下,排序数由随机数产生。父节点从0开始,父节点与左、右孩子的位置关系为:

(父节点)father :  i      (左孩子)left :  i * 2 + 1     (右孩子)right : i * 2 + 2 

代码如下:

/*****************************************Copyright (c) 2015 Jingshuang Hu    @filename:demo.c @datetime:2015.09.25  @author:HJS  @e-mail:eleftheria@163.com  @blog:http://blog.csdn.net/hujingshuang ******************************************/#include <stdio.h>#include <stdlib.h>#include <math.h>/*****************************************/#define N 15//元素个数#define positive 0//正向遍历#define opposite 1//反向遍历/*****************************************/void Heap_Sort(int *data, int n);//堆排序void Heap_Creat(int *data, int n);//创建堆void Heap_Max_Adjust(int *data, int pos, int n);//调整为最大堆void Heap_Show(int *data, int n, int way);//显示堆/*****************************************/int main(){int i = 0;int data[N] = {0};srand((unsigned int)NULL);for (i = 0; i < N; i++){data[i] = rand() % 50 + rand() % 50;}//显示随机数printf("原数据:");Heap_Show(data, N, positive);//创建最大堆Heap_Creat(data, N);printf("最大堆:");Heap_Show(data, N, positive);printf("\n");//堆排序Heap_Sort(data, N);printf("\n堆排序:");Heap_Show(data, N, opposite);return 0;}/*****************************************/void Heap_Show(int *data, int n, int way){int i = 0;if (!way)//遍历方式{for (i = 0; i < n - 1; i++){printf("%d ", data[i]);}printf("%d\n", data[i]);}else{for (i = n - 1; i > 0; i--){printf("%d ", data[i]);}printf("%d\n", data[i]);}}/*****************************************/void Heap_Sort(int *data, int n){int temp = 0;while(n){//顶、底互换(最大值出列,放在末尾)temp = data[0];data[0] = data[n - 1];data[n - 1] = temp;n--;//保护出列元素Heap_Max_Adjust(data, 0, n);//自上而下printf("调整堆:");Heap_Show(data, N, positive);}}/*****************************************/void Heap_Creat(int *data, int n){int i = 0;for (i = (n / 2) - 1; i >= 0; i--){Heap_Max_Adjust(data, i, n);}}/*****************************************/void Heap_Max_Adjust(int *data, int pos, int n){int temp = 0;int father = pos;//父节点位置int left = pos * 2 + 1;//左孩子位置int right = pos * 2 + 2;//右孩子位置if (father < (n / 2)){if (right < n)//有两个孩子{//情况:①父节点与两个孩子相等②左右孩子相等且比父节点大     解决办法:父节点与左孩子(或是右孩子)互换if ((data[left] >= data[father]) && (data[left] >= data[right]))//此处为父节点与左孩子互换{temp = data[left];data[left] = data[father];data[father] = temp;Heap_Max_Adjust(data, left, n);}else if ((data[right] > data[father]) && (data[right] > data[left])){temp = data[right];data[right] = data[father];data[father] = temp;Heap_Max_Adjust(data, right, n);}}else//只有左孩子{if (data[left] > data[father])//相等不用互换{temp = data[left];data[left] = data[father];data[father] = temp;}}}}

        在码完代码后,测试发现,随机数中如果没有出现相同的值,则可以正常正确排序;但是如果有两个及其以上的相同值,就会出现排序错误。经调试发现,未考虑到出现相同值得情况,如代码注释中的情况①②。上述代码已修正,是最终可用的版本。


0 0