选择排序之堆排序
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; }
相关文章推荐
- 排序算法复习(Java实现):插入,冒泡,选择,Shell,快速排序, 归并排序,堆排序,桶式排序,基数排序
- 几种常用的排序算法(快速排序,希尔排序,堆排序,选择排序,冒泡排序)
- 选择排序和堆排序
- 选择排序---简单选择排序 堆排序
- 【Java】八个常用的排序算法:插入排序、冒泡排序、选择排序、希尔排序 、快速排序、归并排序、堆排序和LST基数排序
- 元素排序几种常用的排序算法的分析及java实现(希尔排序,堆排序,归并排序,快速排序,选择排序,插入排序,冒泡排序)
- 选择排序、快速排序、希尔排序、堆排序不是稳定的排序算法,而冒泡排序、插入排序、归并排序和基数排序是稳定的排序算法。
- 数据结构&算法实践—【排序|选择排序】堆排序
- 冒泡排序、选择排序、堆排序、快速排序、插入排序算法复杂度分析与算法实现(自己总结与转)
- java中各种常用排序实现(直接插入排序、直接选择排序、堆排序、冒泡排序、快速排序和归并排序)
- 插入排序、冒泡排序、选择排序、希尔排序、快速排序、归并排序、堆排序和LST基数排序——JAVA实现
- 选择类排序:选择排序,堆排序
- 冒泡排序 快速排序 选择排序 堆排序 直接插入排序 希尔排序 归并排序
- 排序算法: 冒泡排序, 快速排序,希尔排序,直接插入排序 ,直接选择排序,归并排序,堆排序
- 数据结构学习笔记5-寻找最小的k个数(选择排序和堆排序)
- 选择排序之堆排序
- 常用排序算法(包括:选择排序,堆排序,冒泡排序,选择排序,快速排序,归并排序)
- 选择排序——堆排序
- 常用排序算法(冒泡、插入、选择、快速排序、堆排序)
- 第十六周项目5—选择排序之堆排序