距离上次的排序算法文章已通过了蛮久了,今天终于有时间来写写高级的排序,若有不当请多指教!java
归并排序
快速排序
public class MergeSort { private static int[] temp;//临时数组 public static void sort(int[] a) { temp=new int[a.length];//避免在递归中频繁新建数组 sort(a,0,a.length-1); } private static void sort(int[] a,int low,int hig) { if (hig<=low) return; int mid=low+(hig-low)/2; sort(a, low, mid);//左边排序 sort(a, mid+1, hig);//右边排序 merge(a,low,mid,hig);//将两个有序子数组归并 } //合并子数组 public static void merge(int[] a,int low,int mid,int hig) { //i为左序列索引、j为右序列索引 int i=low,j=mid+1; //将a[low..hig]复制到temp[low..hig] for (int k = low; k <= hig; k++) { temp[k]=a[k]; } for (int k = low; k <= hig; k++) { if (i>mid) a[k]=temp[j++]; //左边用尽则取右边元素 else if (j>hig) a[k]=temp[i++]; //右边用尽则取左边元素 else if (temp[i]<temp[j]) a[k]=temp[i++]; //比较左右取小值 else a[k]=temp[j++]; } } }
简单快速排序
快速排序(Quick Sort)使用分治法策略。 它的基本思想是:选择一个基准数,经过一趟排序将要排序的数据分割成独立的两部分;其中一部分的全部数据都比另一部分的全部数据都 要小。而后,再按此方法对这两部分数据分别进行快速排序,整个排序过程能够递归进行,以此达到整个数据变成有序序列。算法
快速排序和归并排序正好相反:数组
平均 | 最好 | 最坏 | 空间 | 稳定性 |
---|---|---|---|---|
O(nlogn) | O(nlogn) | O(n^2) | O(logn) | 不稳定 |
public class QuickSort { public static void sort(int[] a){ shuffle(a);//虚拟方法,打乱数组以加快排序 sort(a,0,a.length-1); } private static void sort(int[] a,int low,int hig) { if (hig<=low) return; int j=partition(a,low,hig); sort(a, low, j-1); sort(a, j+1, hig); } private static int partition(int[] a, int low, int hig) { int i=low,j=hig+1; int v=a[low];//切分元素 while(true){ while(a[++i]<v) if(i==hig) break;//从左侧开始寻找比v大的元素 while(v<a[--j]) if(j==low) break;//从右侧开始寻找比v小的元素 if(i>=j) break; //指针相遇,退出主循环 //交换i、j的值 swap(a,i, j); } //交换切分元素v和a[j] swap(a, low, j); return j; } private static void swap(int[] a,int i,int j){ int t; t=a[i]; a[i]=a[j]; a[j]=t; } }
将sort()中的语句优化
if (hig <= low) return;
替换成ui
if (hig <= low + M){ InsertSort.sort(a,low,hig); return; }
对于含有大量重复元素
的数组,使用三向切分快速排序
进行改进spa
三向切分的快速排序
从左到右遍历数组一次,维护一个指针 lt 使得 a[ low…lt-1 ] 中的元素小于v,一个指针 gt 使得 a[ gt+1…hig ] 中的元素都大于v,一个指针 i 使 a[ lt…i-1 ] 中的元素都等于v,a[ i…gt ] 中的元素都还未肯定3d
咱们对a[i]进行三向比较来处理如下状况:指针
public class QuickSort3Way { public static void sort(int[] a) { sort(a, 0, a.length - 1); } private static void sort(int[] a, int low, int hig) { if (hig <= low) return; //a[ low..lt-1 ] 中的元素小于v //a[ gt+1..hig ] 中的元素都大于v //a[ lt..i-1 ] 中的元素都等于v int lt = low, i = low + 1, gt = hig; int v = a[low]; while (i <= gt) { if (a[i] < v) swap(a, lt++, i++); else if (a[i] > v) swap(a, i, gt--); else i++; } sort(a, low, lt - 1); sort(a, gt + 1, hig); } //交换数组元素 private static void swap(int[] a, int i, int j) { int temp = a[i]; a[i] = a[j]; a[j] = temp; } }
《算法4》第四版code