各种排序算法总结
来源:互联网 发布:数据挖掘的案例分析 编辑:程序博客网 时间:2024/05/21 20:50
排序的稳定性和复杂度
不稳定:
选择排序(selection sort)— O(n2)
快速排序(quicksort)— O(nlog2n)平均时间, O(n2)最坏情况;对于大的、乱序串列一般认为是最快的已知排序
堆排序 (heapsort)— O(nlog2n)
希尔排序 (shell sort)— O(n(1+s)) s为0~1的数
基数排序(radix sort)— O(n·k)需要O(n)额外存储空间 (K为特征个数)
稳定:
插入排序(insertion sort)— O(n2)
冒泡排序(bubble sort)— O(n2)
归并排序 (merge sort)— O(nlog2n);需要O(n)额外存储空间
二叉树排序(Binary tree sort)— O(nlogn);需要O(n)额外存储空间
计数排序 (counting sort) — O(n+k);需要O(n+k)额外存储空间,k为序列中Max-Min+1
桶排序 (bucket sort)— O(n);需要O(k)额外存储空间
插入排序
插入排序的基本思想是:将第i个记录的关键字Ki与前面记录r[1]~r[i-1]的关键字从后向前进行顺次比较,将所有关键字大于Ki的记录依次向后移动一个位置,直到遇到一个关键字小于或等于Ki的记录,该记录的位置即为r[i]的插入位置。
如:
将33,12,25,46,33,68,19,80排序
void InsertSort(int r[], int n)//n为需要比较数个数{ int i,j; for(int i=2;i<=n;i++) { if(r[i]<r[i-1])//如果r[i]>r[i-1],则为正确序列,不用排序 { r[0]=r[i];//监视哨备份,即将r[i]作为关键字 for(j=i-1;r[0]<r[j];j--) { r[j+1]=r[j]; //记录后移 } r[j+1]=r[0];//插入到正确位置 } }}
希尔排序
希尔排序的基本思想是:将需要排序的序列划分成为若干个较小的子序列,对子序列进行插入排序,通过则插入排序能够使得原来序列成为基本有序。这样通过对较小的序列进行插入排序,然后对基本有序的数列进行插入排序,能够提高插入排序算法的效率。
希尔排序的划分子序列不是像归并排序那种的二分,而是采用的叫做增量的技术,例如有八个元素的数组进行希尔排序,首先选择增量为8/2=4。
r[1]和r[5]比较,r[2]和r[6]比较……
如:
将46,25,68,33,33,19,12,80排序
void ShellSort(int r[], int n)//n为需要比较数个数{ int i,j; int dk;//dk为增量 for(dk=n/2;d>=1;dk=dk/2) { for(i=dk+1;i<=n;i++) { if(r[i]<r[i-dk])//如果r[i]>r[i-dk],则为正确序列,不用排序 { r[0]=r[i];//监视哨备份,即将r[i]作为关键字 for(j=i-dk;j>0&&r[0]<r[j];j-=dk) { r[j+dk]=r[j]; //记录交换 } r[j+dk]=r[0];//插入到正确位置 } } }}
冒泡排序
冒泡排序的基本思想是:顺次比较相邻两个记录的关键字大小,如果逆序就交换位置。
void BubbleSort(int r[], int n)//n为需要比较数个数{ int i,j,temp; int flag=1;//flag为标志位 for(i=1;i<=n-1&&flag;i++) { flag=0;//如果顺序正确则不进行比较,直接输出。 for(j=1;j<=n-i;j++) { if(r[j]>r[j+1]) { temp=r[j]; r[j]=r[j+1]; r[j+1]=temp; flag=1; } } }}
快速排序
快速排序的基本思想是:从待序列中任意选择一个记录,以该记录为关键字,凡小于该关键字的记录均移动到该记录之前,大于该关键字的记录移动到该关键字之后。致使一趟排序之后,记录的无序序列被分割成左右两个子序列,然后再分别对两个子序列进行递归快排,直到每个子序列只含有一个记录为止。
如:
将46,68,12,25,33,80,19,33排序
void QKpass(int r[],int low,int high)//low,high分别是标志位{ r[0]=r[low]; while(low<high)//当标志位重叠时结束 { while(low<high&&r[high]>r[0])//如果high>关键字,前移 { --high; } r[low]=r[high];//如果high<关键字,将high赋给low while(low<high&&r[low]<r[0])//如果low<关键字,后移 { ++low; } r[high]=r[low]; //如果low>关键字,将low赋给high } r[low]=r[0];//当标志位重叠时,将r[0]关键字赋值给r[low] return low;//返回标志位}void QKSort(int r[],int low,int high){ int pos; if(low<high) { pos=QKpass(r,low,high); QKSort(r,low,pos-1);//对比关键字小的部分序列的快排 QKSort(r,pos+1,high);//对比关键字大的部分序列的快排 } }
简单选择排序
简单选择排序的基本思想是:从第一个记录开始遍历,每一趟找出一个最小值。即,第一趟,r[1]与r[2]~r[n]每一个进行比较,如果r[i]<r[1]
,则r[1]和r[i]值进行交换。第二趟,r[2]与r[3]~r[n]每一个进行比较,如果r[i]<r[2]
,则r[2]和r[i]值进行交换…….
如:
将33,68,46,33,25,80,19,12排序
void SelectSort(int r[],int n){ int k,temp; for(int i=0;i<=n-1;i++) { k=i; for(j=i+1;j<=n-1;j++) { if(r[j]<r[k]) { k=j; } } if(k!=i) { temp=r[i]; r[i]=r[k]; r[k]=temp; } } }
堆排序
堆排序的基本思想是:先建一个“大顶堆”,即先选一个关键字最大的记录,然后与序列中最后一个记录交换,之后继续对序列中前n-1记录进行“筛选”,重新将它调整为一个“大顶堆”,再将堆顶记录和第n-1个记录交换,如此反复,直至排序结束。
如:
对46,12,33,72,68,19,80,33进行堆排序
堆的筛选,过程如下:
void HeapAdjust(int r[],int s,int n){ int temp=r[s]; for(int j=2*s;j<=n;j*=2) { if(j<n&&r[j]>r[j+1])//沿值较小的节点向下筛选 j++; if(temp<r[j]) break; r[s]=r[j]; s=j; } r[s]=temp;//插入}
建初始堆过程如下:
void CreatHeap(int r[],int n){ for(i=n/2;i>=1;i--) HeapAdjust(r,i,n);}
堆排序过程如下:
void HeapSort(int r[],n){ CreateHeap(r,n); for(i=n;i>=2;i--) { r[0]=r[1]; r[1]=r[i]; r[i]=r[0]; HeapAdjust(r,1,i-1); }}
基数排序
基数排序的基本思想是:对于数字型或字符型的单关键字,可以看做是由多个位数或多个字符构成的多关键字。
如:
对921,435,628,285,862,225,448,193,430排序。
首先按照“个位数”取值,分别为0,1…….,9“分配”成10组,之后按照0到9收集在一起。
然后按照“十位数”分配收集。
然后“百位数”。
然后……
//提取关键字第m位的数字值int digit(KeyType k,int m,int r){ int i,d; if(m==0) return k%r; d=r; for(i=1;i<m;i++) d*=r; return ((int)(key/d)%r); }
//基数排列void RadixSort(Type r[],int n,int m,int r)//L中的关键字为m位r进制数,L的长度为n{ LinkQueue *Queue; int i,j,k; q=(LinkQueue *)malloc(r*sizeof(LinkQueue)); for(i=0;i<r;i++) InitQueue(&Queue[i]); for(i=0;i<m;i++) { for(j=0;j<n;j++) { k=digit(L[j].key,i,r); EnterQueue(&Queue[k],L[j]); } k=0; for(j=0;j<r;j++) for(;!IsEmptyQueue(Queue[j]);k++) DeleteQueue(&Queue[j],&(L[k])); } }
- 各种排序算法总结
- 各种排序算法总结
- 各种排序算法总结
- 各种排序算法总结
- 各种排序算法总结
- 各种排序算法总结
- 各种排序算法总结
- 各种排序算法总结
- 各种排序算法总结
- 各种排序算法总结
- 各种排序算法总结
- 各种排序算法总结
- 各种排序算法总结
- 各种排序算法总结
- 各种排序算法总结
- 各种排序算法总结
- 各种排序算法总结
- 各种排序算法总结
- Android应用优化之流畅度
- 状态机跑飞的惨案
- servletcontext与application的联系
- Socket编程(网络协议一)
- Linphone-android 登录过程增加自定义消息头流程分析
- 各种排序算法总结
- java html转pdf 中文乱码
- Markdown
- 正定矩阵、负定矩阵、半正定矩阵、半负定矩阵
- deformable convolutional networks
- Redis集群
- python自学2
- 整合spring session 用redis 做缓存
- ④NuPlayer播放框架之Renderer源码分析