排序算法
2016-02-06 20:43
274 查看
(一)冒泡排序算法
1.基本思想:两两比较相邻记录的关键字,如果反序则交换,直到没有反序的记录为止;
2.例子:
3.代码:
(1)在每次循环中,通过交换反序的相邻数据,使较小的数字如同气泡般慢慢地浮到上面;
(2)若在一次循环中,没有数字往上冒,证明已经排好序了;
(二)直接插入排序
1.基本思想:将一个记录插入到已经排好序的有序表中,从而得到一个新的,记录数增1的有序表;
2.例子:
3.代码:
(1)每次循环都将新的数据插入到之前的数据中,需要对原有的数据做移动,空出一个合适的位置;
(三)简单选择排序
1.基本思想:通过n-i次关键字间的比较,从n-i+1个记录中选出关键字最小的记录,并和第i(1=<i<=n)个记录交换之;
2.例子:
3.代码:
(1)每次循环都选择一个最小的数,交换放到前面去;
(2)简单选择排序算法总体上优于冒泡排序算法,因为其交换数据的次数少;上述例子中,最多做8次交换;
(四)快速排序
1.基本思想:先从数列中取出一个数作为基准数,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边,再对左右区间重复以上步骤,直到各区间只有一个数(分治思想);
2.例子:
3.代码:
(五)希尔排序
1.基本思想:将相距某个“增量”的记录组成一个子序列,在这些子序列内分别进行直接插入排序,当整个序列基本有序时,再对全体记录进行一次直接插入排序;
2.例子:
(1)原始记录如下:
(2)根据增量分隔子序列并内部排序(注意最终增量必须为1):
3.代码:
(六)堆排序
1.基本思想:将待排序的序列构造成一个大顶堆;此时,整个序列的最大值就是堆顶的根结点;将它移走(其实就是将其与堆数组的末尾元素交换,此时末尾元素就是最大值),然后将剩余的n-1个序列重新构造成一个堆,这样就会得到n个元素中的次大值,如此反复执行,便能得到一个有序序列;
2.例子:
PS:堆排序中,堆是以层序遍历的形式存储在数组中的;建堆的过程其实就是依次调整堆的过程,从最后一个非叶子结点开始调整;
3.代码:
(七)归并排序
1.基本思想:假设初始序列含有n个记录,则可以看成是n个有序的子序列,每个子序列的长度为1,然后两两归并,得到n/2个长度为2或者1的有序子序列;再两两归并,。。。,如此重复,直至得到一个长度为n的有序序列为止,这种排序方法称为2路归并排序;
2.例子:
(八)总结
1.排序算法对比:
2.排序算法分类:
1.基本思想:两两比较相邻记录的关键字,如果反序则交换,直到没有反序的记录为止;
2.例子:
3.代码:
(1)在每次循环中,通过交换反序的相邻数据,使较小的数字如同气泡般慢慢地浮到上面;
(2)若在一次循环中,没有数字往上冒,证明已经排好序了;
(二)直接插入排序
1.基本思想:将一个记录插入到已经排好序的有序表中,从而得到一个新的,记录数增1的有序表;
2.例子:
3.代码:
(1)每次循环都将新的数据插入到之前的数据中,需要对原有的数据做移动,空出一个合适的位置;
(三)简单选择排序
1.基本思想:通过n-i次关键字间的比较,从n-i+1个记录中选出关键字最小的记录,并和第i(1=<i<=n)个记录交换之;
2.例子:
3.代码:
(1)每次循环都选择一个最小的数,交换放到前面去;
(2)简单选择排序算法总体上优于冒泡排序算法,因为其交换数据的次数少;上述例子中,最多做8次交换;
(四)快速排序
1.基本思想:先从数列中取出一个数作为基准数,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边,再对左右区间重复以上步骤,直到各区间只有一个数(分治思想);
2.例子:
3.代码:
(五)希尔排序
1.基本思想:将相距某个“增量”的记录组成一个子序列,在这些子序列内分别进行直接插入排序,当整个序列基本有序时,再对全体记录进行一次直接插入排序;
2.例子:
(1)原始记录如下:
(2)根据增量分隔子序列并内部排序(注意最终增量必须为1):
3.代码:
(六)堆排序
1.基本思想:将待排序的序列构造成一个大顶堆;此时,整个序列的最大值就是堆顶的根结点;将它移走(其实就是将其与堆数组的末尾元素交换,此时末尾元素就是最大值),然后将剩余的n-1个序列重新构造成一个堆,这样就会得到n个元素中的次大值,如此反复执行,便能得到一个有序序列;
2.例子:
PS:堆排序中,堆是以层序遍历的形式存储在数组中的;建堆的过程其实就是依次调整堆的过程,从最后一个非叶子结点开始调整;
3.代码:
//生成大根堆 void HeapAdjust(int SortData[],int StartIndex, int Length) { while(2*StartIndex+1 < Length) { int MinChildrenIndex = 2*StartIndex+1 ; if(2*StartIndex+2 < Length ) { //判断是否有右子树,若有的话则取较大的子树的index if(SortData[2*StartIndex+1]<SortData[2*StartIndex+2]) { MinChildrenIndex = 2*StartIndex+2; } } if(SortData[StartIndex] < SortData[MinChildrenIndex]) { //交换i与MinChildrenIndex的数据 int tmpData =SortData[StartIndex]; SortData[StartIndex] =SortData[MinChildrenIndex]; SortData[MinChildrenIndex] =tmpData; //堆被破坏,需要重新调整 StartIndex = MinChildrenIndex ; } else { //比较左右孩子均大则堆未破坏,不再需要调整 break; } } return; } //堆排序 void HeapSortData(int SortData[], int Length) { int i=0; //将Hr[0,Lenght-1]建成大根堆 for (i=Length/2-1; i>=0; i--) { HeapAdjust(SortData, i, Length); } for (i=Length-1; i>0; i--) { //与最后一个记录交换 int tmpData =SortData[0]; SortData[0] =SortData[i]; SortData[i] =tmpData; //将H.r[0..i]重新调整为大根堆 HeapAdjust(SortData, 0, i); } return; } int main() { int SortData[] ={12,36,24,85,47,30,53,91}; HeapSortData(SortData, 8); for (int i=0; i<8; i++) { std::cout<<SortData[i]<<" "; } std::cout<<std::endl; return 0; }
(七)归并排序
1.基本思想:假设初始序列含有n个记录,则可以看成是n个有序的子序列,每个子序列的长度为1,然后两两归并,得到n/2个长度为2或者1的有序子序列;再两两归并,。。。,如此重复,直至得到一个长度为n的有序序列为止,这种排序方法称为2路归并排序;
2.例子:
(八)总结
1.排序算法对比:
2.排序算法分类:
相关文章推荐
- 1002. 写出这个数 (20)
- Android Studio 简单设置
- Project文档编辑和权限分配
- 1001. 害死人不偿命的(3n+1)猜想 (15)
- PAT (Basic Level)1013. 数素数
- Interleaving String -- LeetCode
- ZwOpenSymbolicLinkObject routine
- 蓝桥杯 - 道路和航路(SPFA)
- hostname 是个kernel参数
- android数据存储的四种方案(二)
- POJ 3069
- 项目学习的方法与经验
- ADO.NET之command更新数据(视图版)
- c#之多态的一个应用
- linear-gradient()图像渐变属性详解
- hdu 4509
- nyoj779兰州烧饼
- 回调在python中
- 正则表达式
- LeetCode47. Permutations II