几种排序
2010-12-01 09:36
197 查看
Sort排序是经典问题,关于排序的算法也有很多,根据平时的使用习惯,下面简单总结了几种常见的,简单易懂的排序算法。其中部分内容参考了数据结构自考网,还有各位大神,小鬼的blog。 目录:(按策略划分)交换排序 冒泡排序(BubbleSort) 快速排序(QuickSort)插入排序 直接插入排序(InsertionSort) 希尔排序(Shell Sort)选择排序 直接选择排序(Selection Sort) 堆排序(HeapSort)以上几种排序方法比较 BubbleSort经典冒泡排序,两项比较,如果大小关系和关键字相反就交换位置#include<stdio.h>void main(){ int i,j,t; int a[9]={9,2,1,5,6,3,4,7,8}; for(i=1;i<9;i++) for(j=0;j<8;j++) if(a[j]>a[i]) { t=a[j];a[j]=a[i];a[i]=t; } for(i=0;i<9;i++) printf("%d ",a[i]); printf("/n");}另:算法思想:将被排序的记录数组R[1..n]垂直排列,每个记录R[i]看作是重量为R[i].key的气泡。根据轻气泡不能在重气泡之下的原则,从下往上扫描数组R:凡扫描到违反本原则的轻气泡,就使其向上"飘浮"。如此反复进行,直到最后任何两个气泡都是轻者在上,重者在下为止。QuickSort快速排序(qsort),分治递归思想制定标志变量,以其分割数组,并对前数组,后数组分别递归调用函数,直到数组长度为1,则完成排序#include <iostream> #include <stdlib.h> #include <ctime> using namespace std; int partition(int *A,int p,int r) //数组分割 { int i,j,x; x=A[r]; //指定标志值 i=p-1; //保证第一次找到的小于,等于X的数被换到 for(j=p;j<r;j++) //a[0],第二个放到a[1]…… if(A[j] <= x) //大于X的数不会使i变大 { i++; swap<int>(A[i],A[j]); } swap<int>(A[i+1],A[r]); //前i个数都小于a[r] return i+1; //返回a[r],即分割数组的标志值位置} void quicksort(int *A,int p,int r) { if(p >= r) return ; int q=partition(A,p,r); quicksort(A,p,q-1); //q位置的数不用参与排序,因为当前位置就是 quicksort(A,q+1,r); //其正确位置} void Show(int *A,int p,int r) { for(int i=p;i<=r;i++) cout<<A[i]<<" "; cout<<endl; } void main() { int i; int A[10]; srand((unsigned int)time(NULL)); for(i=0;i<10;i++) A[i]=rand()%20; Show(A,0,9); quicksort(A,0,9); Show(A,0,9); system("pause"); } InsertionSort插入排序,每次将一个待排序的记录,按其关键字大小插入到前面已经排好序的子文件中的适当位置,直到全部记录插入完成为止。默认当前项前面的序列有序,并在前面的序列中查找第一个比当前项大(小)的数,找到后,把该数以及其后面的数全部后移一位,空出来的位置就是当前的位置。插入排序的操作很类似打牌时整理手中的牌,很有意思的方法。#include<stdio.h>void main(){ int i,j,t; int a[9]={9,2,1,5,6,3,4,7,8}; for(i=1;i<9;i++) { if(a[i]<a[i-1])//若R[i].key大于等于有序区中所有的keys,则R[i] //应在原有位置上 { t=a[i]; for(j=i-1;j>=0;j--) if(a[j]>t) { a[j+1]=a[j]; a[j]=t; } else break; } } for(i=0;i<9;i++) printf("%d ",a[i]); printf("/n");} 另:希尔排序实质上就是分组插入排序,效率较直接插入排序有很大提高,但是不稳定。 SelectionSort选择排序,在待排数据中查找最小(大)值放在第一位,然后在剩下的数中查找第二小(大)的数放在第二位,……依次操作#include<stdio.h>void main(){ int i,j,t,min; int a[9]={9,2,1,5,6,3,4,7,8}; for(i=0;i<9;i++) { min=i; for(j=i+1;j<9;j++) if(a[j]<a[min]) min=j; t=a[i];a[i]=a[min];a[min]=t; //t做存储单元,也可以用a[0]做存储单元 } for(i=0;i<9;i++) printf("%d ",a[i]); printf("/n");} 直接选择排序时就地排序,是不稳定的排序。 HeapSort堆排序堆实质上是满足如下性质的完全二叉树:树中任一非叶结点的关键字均不大于(或不小于)其左右孩子(若存在)结点的关键字。根结点(亦称为堆顶)的关键字是堆里所有结点关键字中最小者的堆称为小根堆。根结点的关键字是堆里所有结点关键字中最大者,称为大根堆。堆中任一子树亦是堆。堆排序可通过树形结构保存部分比较结果,可减少比较次数。堆排序利用了大根堆(或小根堆)堆顶记录的关键字最大(或最小)这一特征,使得在当前无序区中选取最大(或最小)关键字的记录变得简单。步骤:建堆(假设是大根堆),把堆顶元素a[1]和最后一个元素a
交换位置,则a
就是最大值;然后以a[1]到a[n-1]为对象,调整建堆,再把堆顶元素和最后一个元素(现在是a[n-1])交换,则a[n-1]到a
就是有序的了。以此重复操作即可。 以上几种排序方法比较平均时间:(1) 平方阶(O(n2))排序一般称为简单排序,例如直接插入、直接选择和冒泡排序;(2)线性对数阶(O(nlgn))排序 如快速、堆排序;(3)O(n1+£)阶排序 £是介于0和1之间的常数,即0<£<1,如希尔排序;各种排序方法比较 简单排序中直接插入最好,快速排序最快,当文件为正序时,直接插入和冒泡均最佳。影响排序效果的因素 因为不同的排序方法适应不同的应用环境和要求,所以选择合适的排序方法应综合考虑下列因素: 1待排序的记录数目n;2记录的大小(规模);3关键字的结构及其初始状态;4对稳定性的要求;5语言工具的条件;6存储结构;7时间和辅助空间复杂度等。不同条件下,排序方法的选择
(1)若n较小(如n≤50),可采用直接插入或直接选择排序。 当记录规模较小时,直接插入排序较好;否则因为直接选择移动的记录数少于直接插入,应选直接选择排序为宜。(2)若文件初始状态基本有序(指正序),则应选用直接插入、冒泡或随机的快速排序为宜;(3)若n较大,则应采用时间复杂度为O(nlgn)的排序方法:快速排序、堆排序; 快速排序是目前基于比较的内部排序中被认为是最好的方法,当待排序的关键字是随机分布时,快速排序的平均时间最短; 堆排序所需的辅助空间少于快速排序,并且不会出现快速排序可能出现的最坏情况。这两种排序都是不稳定的。
交换位置,则a
就是最大值;然后以a[1]到a[n-1]为对象,调整建堆,再把堆顶元素和最后一个元素(现在是a[n-1])交换,则a[n-1]到a
就是有序的了。以此重复操作即可。 以上几种排序方法比较平均时间:(1) 平方阶(O(n2))排序一般称为简单排序,例如直接插入、直接选择和冒泡排序;(2)线性对数阶(O(nlgn))排序 如快速、堆排序;(3)O(n1+£)阶排序 £是介于0和1之间的常数,即0<£<1,如希尔排序;各种排序方法比较 简单排序中直接插入最好,快速排序最快,当文件为正序时,直接插入和冒泡均最佳。影响排序效果的因素 因为不同的排序方法适应不同的应用环境和要求,所以选择合适的排序方法应综合考虑下列因素: 1待排序的记录数目n;2记录的大小(规模);3关键字的结构及其初始状态;4对稳定性的要求;5语言工具的条件;6存储结构;7时间和辅助空间复杂度等。不同条件下,排序方法的选择
(1)若n较小(如n≤50),可采用直接插入或直接选择排序。 当记录规模较小时,直接插入排序较好;否则因为直接选择移动的记录数少于直接插入,应选直接选择排序为宜。(2)若文件初始状态基本有序(指正序),则应选用直接插入、冒泡或随机的快速排序为宜;(3)若n较大,则应采用时间复杂度为O(nlgn)的排序方法:快速排序、堆排序; 快速排序是目前基于比较的内部排序中被认为是最好的方法,当待排序的关键字是随机分布时,快速排序的平均时间最短; 堆排序所需的辅助空间少于快速排序,并且不会出现快速排序可能出现的最坏情况。这两种排序都是不稳定的。
相关文章推荐
- 极角排序的几种方法
- 常见的几种排序
- 几种常用的排序方法3--选择排序
- 几种常见的排序算法之比较
- IOS几种简单有效的数组排序方法
- IOS几种简单有效的数组排序方法
- java中数组的几种排序
- C语言——常见的几种排序的实现
- Linq的筛选、排序等几种用法(VS2010)
- hive中的几种排序的区别
- 几种排序的直观解释
- 极角排序的几种方法
- java 数组常见的几种排序
- 几种常见排序的代码和时间比较
- JavaScript的几种排序方法
- Java实现几种常见排序方法
- java的几种常用排序方法集合
- 关于NSArray的几种排序:
- 几种数组排序方法及二维数组作参数传递
- 几种内部排序算法总结!(冒泡排序、快速排序、直接插入排序、拆半插入排序、简单选择排序)