赞
踩
十种排序算法的基本特性:
排序算法 | 平均时间复杂度 | 最好情况 | 最坏情况 | 空间复杂度 | 排序方式 | 稳定性 |
---|---|---|---|---|---|---|
快速排序 | Ο(nlogn) | Ο(nlogn) | Ο(n2) | Ο(logn) | in-place | 不稳定 |
归并排序 | Ο(nlogn) | Ο(nlogn) | Ο(nlogn) | Ο(n) | out-place | 稳定 |
堆排序 | Ο(nlogn) | Ο(nlogn) | Ο(nlogn) | Ο(1) | in-place | 不稳定 |
shell排序 | Ο(nlogn) | Ο(nlog2n) | Ο(nlog2n) | Ο(1) | in-place | 不稳定 |
插入排序 | Ο(n2) | Ο(n) | Ο(n2) | Ο(1) | in-place | 稳定 |
冒泡排序 | Ο(n2) | Ο(n) | Ο(n2) | Ο(1) | in-place | 稳定 |
选择排序 | Ο(n2) | Ο(n2) | Ο(n2) | Ο(1) | in-place | 不稳定 |
计数排序 | Ο(n+k) | Ο(n+k) | Ο(n+k) | Ο(k) | out-place | 稳定 |
桶排序 | Ο(n+k) | Ο(n+k) | Ο(n2) | Ο(n+k) | out-place | 稳定 |
基数排序 | Ο(n*k) | Ο(n*k) | Ο(n*k) | Ο(n+k) | out-place | 稳定 |
*稳定性:多个相同的值的相对位置在算法结束时是否产生变动。
一、快速排序
快速排序由C. A. R. Hoare在1960年提出。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
原理:
设要排序的数组是A[0]……A[N-1],首先任意选取一个数据(通常选用数组的第一个数)作为关键数据,然后将所有比它小的数都放到它左边,所有比它大的数都放到它右边,这个过程称为一趟快速排序。
1)设置两个变量i、j,排序开始的时候:i=0,j=N-1;
2)以第一个数组元素作为关键数据,赋值给key,即key=A[0];
3)从j开始向前搜索,即由后开始向前搜索(j–),找到第一个小于key的值A[j],将A[j]和A[i]的值交换;
4)从i开始向后搜索,即由前开始向后搜索(i++),找到第一个大于key的A[i],将A[i]和A[j]的值交换;
5)重复第3、4步,直到i=j; (3,4步中,没找到符合条件的值,即3中A[j]不小于key,4中A[i]不大于key的时候改变j、i的值,使得j=j-1,i=i+1,直至找到为止。找到符合条件的值,进行交换的时候i, j指针位置不变。另外,i==j这一过程一定正好是i+或j-完成的时候,此时令循环结束)。
变种:1)随机化快排 2)平衡快排 3)外部快排
实现:
//递归法 private static int quickOne(int data[],int left,int right) { if(data==null) return -1; int key=data[left]; while(left<right) { while(left<right && data[right]>=key) right--; data[left]=data[right]; while(left<right && data[left]<key) left++; data[right]=data[left]; } data[left]=key; return left; } private static void quickTwo(int data[],int left,int right) { if(data==null) return ; int mid=quickOne(data,left,right); if(left<mid-1) quickTwo(data,0,mid-1); if(mid+1<right) quickTwo(data,mid+1,right); } public static void quickSort1(int data[]) { if(data==null) return ; quickTwo(data,0,data.length-1); }
public static void quickSort2(int data[]) { if(data==null) return ; ArrayQueue queue = new ArrayQueue(); queue.inQueue(0); //最开始序列的首下标为0 queue.inQueue(data.length-1); //最开始序列的尾下标为传入数组的最后一个元素下表 while(!queue.isEmpty()) { int left=queue.outQueue(); int right=queue.outQueue(); int mid=quickOne(data,left,right); if(left<mid-1) //左序列有两个以上元素时,将左序列的首尾下标入队 { queue.inQueue(left); queue.inQueue(mid-1); } if(mid+1<right) //右序列有两个以上元素时,将右序列的首尾下标入队 { queue.inQueue(mid+1); queue.inQueue(right); } } }
二、归并排序
三、堆排序
四、Shell排序
实现:
public static void shellSort(int data[]) { if(data==null) return ; int k=data.length/2+1; while(k>0) { for(int i=0;i<data.length-k;i++) { if(data[i]>data[i+k]) { int t=data[i]; data[i]=data[i+k]; data[i+k]=t; } } k--; } }
五、插入排序
原理:通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。
具体算法:
从第一个元素开始,该元素可以认为已经被排序
取出下一个元素,在已经排序的元素序列中从后向前扫描
如果该元素(已排序)大于新元素,将该元素移到下一位置
重复上述步骤,直到找到已排序的元素小于或者等于新元素的位置
将新元素插入到该位置后
变种:
二分查找插入排序:查找插入位置部分使用二分查找法
伪冒泡插入排序:插入部分使用冒泡排序法
实现:
//普通插入排序 public static void insertionSort(int data[]) { if(data==null) return ; for(int i=1;i<data.length;i++) { int j=0; int t=data[i]; for(j=0;j<i;j++) if(t<=data[j]) break; //将数据插入第一个比它大的数之前 for(int k=i;k>j;k--) { data[k]=data[k-1]; } data[j]=t; } }
//折半插入排序 public static void binarySort(int data[]) { if(data==null) return ; for(int i=1;i<data.length;i++) { int key=data[i]; int low = 0; int high = i-1; for(int j=0;j<i;j++) { while (low<=high) { int mid = (low+high)/2; if(data[mid]== key) { high=mid; break; } else if (data[mid] < key) low = mid+1; else if (data[mid] > key) high = mid-1; } } high++; for(int k=i;k>high;k--) data[k]=data[k-1]; data[high]=key; } }
//伪冒泡插入排序 public static void insertionSort2(int data[]) { if(data==null) return; for(int i=1;i<data.length;i++) { for(int j=i;j>0;j--) { if(data[j]<data[j-1]) //伪冒泡交换 { int t=data[j]; data[j]=data[j-1]; data[j-1]=t; } else break; } } }
六、冒泡排序
实现:
public static void bobSort(int data[]) { if(data==null) return; //保证程序的健壮性! int len = data.length-1; while(len>0){ for(int i=0;i<len;i++) { if(data[i]>data[i+1]) { int t = data[i]; data[i] = data[i+1]; data[i+1] = t; } } len--; } }
七、选择排序
实现:
//选择排序 public static void selectionSort(int data[]) { for(int i=0;i<data.length;i++) { for(int j=i+1;j<data.length;j++) { if(data[j]<data[i]) { int t = data[j]; data[j] = data[i]; data[i] = t; } } } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。