距離上次的排序算法文章已通過了蠻久了,今天終於有時間來寫寫高級的排序,若有不當請多指教!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