夕拾-数据结构-选择&堆排序
2015-10-10 22:12
281 查看
1.选择排序
记得以前吾最爱的就是选择排序,因为它最容易理解:从当前元素的后面选择一个最小的元素与之交换
2.堆排序
堆排序是快速排序的改进,就如同快速之如冒泡。因为涉及单支变量i*=2,因此i的下标只能从1开始,而堆排序可分2步走:
建立大堆
从最后的分支节点(length/2)开始,让它与孩子节点比较,找到一个大的则与之交换。如此直至顶点即可得到大顶堆。
调整堆
此时顶点是最大的节点,让其与末端节点交换。末端节点成最大节点,软删除末端节点。从顶点向下继续调整,得到新的大顶堆。如此重复,直至剩下1个节点即可
下面是基于交换的思想
和快速排序一样,交换的思想可以改进为填位的思维:
记得以前吾最爱的就是选择排序,因为它最容易理解:从当前元素的后面选择一个最小的元素与之交换
void SelectionSort(int a[],int n) { int i,j,min; //min记录比当前元素小的下标 for(i=0;i<n-1;i++) { min=i; for(j=i+1;j<n;j++) { if(a[min]>a[j]) min=j; //从当前元素后面的序列后选择一个最小的元素 } if(min!=i) Swap(a[i],a[min]); //找到了->交互 } }
2.堆排序
堆排序是快速排序的改进,就如同快速之如冒泡。因为涉及单支变量i*=2,因此i的下标只能从1开始,而堆排序可分2步走:
建立大堆
从最后的分支节点(length/2)开始,让它与孩子节点比较,找到一个大的则与之交换。如此直至顶点即可得到大顶堆。
void HeapSort(int a[],int n) { //从最后的分支节点(length/2)开始,让它与孩子节点比较, //找到一个大的则与之交换,如此直至顶点 for(int i=n/2;i>0;i--) { AdjustDownFill(a,i,n); } //调整堆 for(int i=n;i>1;i--) { Swap(a[i],a[1]); AdjustDownFill(a,1,i-1); } }
调整堆
此时顶点是最大的节点,让其与末端节点交换。末端节点成最大节点,软删除末端节点。从顶点向下继续调整,得到新的大顶堆。如此重复,直至剩下1个节点即可
下面是基于交换的思想
void AdjustDownSwap(int a[],int k,int n) { for(int i=k*2;i<=n;i*=2) //左单支下遍历 { if(i<n && a[i]<a[i+1]) i++; //左孩子存在,且较大 if(a[i]<=a[k]) break; //父节点较大,无需交换 Swap(a[k],a[i]); //孩子节点较大 } }
和快速排序一样,交换的思想可以改进为填位的思维:
void AdjustDownFill(int a[],int k,int n) { a[0]=a[k]; for(int i=k*2;i<=n;i*=2) //左单支下遍历 { if(i<n && a[i]<a[i+1]) i++; //左孩子存在,且较大 if(a[i]<=a[0]) break; //父节点较大,无需交换 a[k]=a[i]; //子节点覆盖父节点 k=i; //子节点设置待被覆盖节点 } a[k]=a[0]; // 最后只把a[0]插入适当的位置即可 }
相关文章推荐
- C/C++ 数据结构练习题1
- C语言数据结构-顺序栈
- 数据结构--树
- 活用各种数据结构——RMQ/树状数组/分桶法和平方分割
- 数据结构实习二2
- 数据结构实习二1
- 02-线性结构1 一元多项式的乘法与加法运算
- 线性表的基本运算及多项式的算术运算
- Java基础知识强化之集合框架笔记72:集合特点和数据结构总结
- TreeSet底层数据结构是二叉树
- C语言数据结构-双链表
- 数据结构基础2_单链表的实现
- 数据结构实验之链表五:单链表的拆分
- C语言数据结构-单链表
- Minimum Inversion Number(线段树)
- 数据结构--栈的构造、插入、删除、得到栈顶元素操作
- 数据结构之链队列
- 数据结构 - AVL木
- 数据结构之五
- 数据结构之四