非递归方法的堆排序实现
2016-07-29 00:00
351 查看
引言
首先需要明确,如何根据父亲结点的位置得知孩子结点的位置,以及如何根据孩子结点的位置得知父亲结点的位置。假设数列索引从0开始,如果父亲结点的索引为i,那么左孩子索引为2i+1,右孩子索引为2i+2;如果孩子结点的索引为j,那么父亲结点的索引为(j-1)/2。
堆排序的核心在于函数voidadjustdown(int*arr,inti,intend),其中第i+1个元素到最后一个元素均已满足堆结构,每次adjustdown可以使当前位置i的元素也满足堆结构。如果是大堆,则经过adjustdown后当前位置的元素最大;如果是小堆,则经过adjustdown后当前位置的元素最小。
以下代码,将数列从小到大排序。采用大堆,并且使用了非递归的方法。函数adjustdown中的五个if语句实际上有一部分是可以合并的,但是为了逻辑清晰,在本代码中,完整保留下来了。注释我写的很用心,相信读者可以看懂。
代码
#include<stdio.h>#include<stdlib.h>#include<string.h>#include<time.h> staticvoidshow(int*arr,intlen){intindex;for(index=0;index<len;index++){printf("%d",arr[index]);}printf("\n");}staticvoidswap(int*left,int*right){inttmp=*left;*left=*right;*right=tmp;}voidadjustdown(int*arr,inti,intend){intkey=arr[i];intp=i;intleft=2*p+1;/*越界就是没孩子*//*只要能进循环,一定有左孩子*/ while(left<=end){/*有右孩子的情况下,大于等于左右孩子不用换*/ if((key>=arr[left])&&(left+1<=end&&key>=arr[left+1])){break;}elseif(key>=arr[left]&&left+1>end)/*没有右孩子,只有左孩子,且大于等于左孩子不用换*/{break;}elseif(left+1<=end&&arr[left+1]>=arr[left]&&key<arr[left+1])/*与右孩子换。要保证有右孩子,且右孩子大于等于左孩子,父亲小于右孩子*/{swap(arr+p,arr+left+1);p=left+1;//父亲与谁换,就到谁的位置了 left=2*p+1;//父亲新的左孩子的位置 }elseif(left+1<=end&&arr[left]>arr[left+1]&&key<arr[left])/*与左孩子换。有右孩子的情况下,右孩子小于左孩子,父亲小于左孩子*/{swap(arr+p,arr+left);p=left;left=2*p+1;}elseif(left+1>end&&arr[left]>key)/*与左孩子换。没右孩子的情况下,只需父亲小于左孩子*/{swap(arr+p,arr+left);p=left;left=2*p+1;}}}voidheap_sort(int*arr,intlen){intp;//最后一个父亲 intend;//最后一个有效下标 /*建一个大顶堆,从最后一个父亲开始调*/ for(p=(len-1-1)/2;p>=0;p--){adjustdown(arr,p,len-1);}/*根结点的值最大,与末尾交换,并继续建立堆结构,再交换...*/ for(end=len-1;end>=1;end--){swap(arr,arr+end);//end已经是最大值 adjustdown(arr,0,end-1);//从arr+1到end-1位置都是满足堆结构的 }}intmain(intargc,char*argv[]){intindex;intarr[10];memset(arr,0,10);srand(time(NULL));for(index=0;index<10;index++){arr[index]=rand()%20+1;}show(arr,10);heap_sort(arr,10);show(arr,10);system("pause");return0;}
相关文章推荐
- DFS遍历中forward、backward以及cross边的界定
- Python线程指南
- [LeetCode] Search in Rotated Sorted Array II
- Dynamic Programming | Set 1 (Overlapping Subproblems Property)
- 服务器设计系列:架构综述
- 算法之美---100幅由程序生成的图像,总有一幅让你感到惊艳[上]
- dbm数据库源代码分析(17):Makefile文件和其他文件
- 我的C++实践(6):模板与继承相结合的威力
- Linux系统管理实践(5):Samba文件共享配置
- Internetworking
- Introduction to Machine Learning
- B样条
- INTERESTING AND OBSCURE INHERITANCE ISSUES WITH CPP
- 数学图形(2.4)网球上的曲线
- 快速排序算法
- 浏览器的工作原理:现代网络浏览器幕后揭秘
- 编程实现Linux下的ls -l
- 从导数谈起
- Linux系统管理实践(3):GRUB系统引导配置
- 机器学习之神经网络模型-上(Neural Networks: Representation)