排序算法总结版
排序算法分類
? ? ?選擇排序:簡單選擇排序、堆排序
? ? ?插入排序:直接插入排序、二分插入排序和希爾排序
? ? ?歸并排序:歸并排序
? ? ?交換排序:冒泡排序、快速排序
? ? ?基數排序:基數排序
算法時間和空間復雜度分析
? ??
? ? ? ? ? ? ? ? ? ? 圖1 ?性能分析
性能具體分析 O(n^2):直接插入排序,簡單選擇排序,冒泡排序。 在數據規模較小時(9W內),直接插入排序,簡單選擇排序差不多。當數據較大時,冒泡排序算法的時間代價最高。性能為O(n^2)的算法基本上是相鄰元素進行比較,基本上都是穩定的。 O(nlogn):快速排序,歸并排序,希爾排序,堆排序。 其中,快排是最好的, 其次是歸并和希爾,堆排序在數據量很大時效果明顯。排序算法精講
?選擇排序:
? ? 簡單選擇排序
? ? ? ?思想:每次找出一個當前最小值并放到合適的位置。
? ? ? ?不穩定排序
? ? ? ?1)首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置
? ? ? ?2)再從剩余未排序元素中繼續尋找最小(大)元素,然后放到已排序序列的末尾。
? ? ? ?3)重復第二步,直到所有元素均排序完畢。? ? ?
? ? 堆排序
? ? ? 思想:利用沉降原理不斷的調整成大(小)根堆
? ? ? 不穩定排序?
1 /** 2 針對數組進行排序 3 堆是一種重要的數據結構,為一棵完全二叉樹, 底層如果用數組存儲數據的話,假設某個元素為序號為i(Java數組從0開始,i為0到n-1),如果它有左子樹,那么左子樹的位置是2i+1,如果有右子樹,右子樹的位置是2i+2,如果有父節點,父節點的位置是(n-1)/2取整。分為最大堆和最小堆,最大堆的任意子樹根節點不小于任意子結點,最小堆的根節點不大于任意子結點。所謂堆排序就是利用堆這種數據結構來對數組排序,我們使用的是最大堆。處理的思想和冒泡排序,選擇排序非常的類似,一層層封頂,只是最大元素的選取使用了最大堆。最大堆的最大元素一定在第0位置,構建好堆之后,交換0位置元素與頂即可。堆排序為原位排序(空間小), 且最壞運行時間是O(nlgn),是漸進最優的比較排序算法。 4 **/ 5 6 //初始化建立大根堆 7 private static void buildMaxHeap(int[] array){ //初始時建立大根堆 8 if(array == null || array.length <= 1){ 9 return; 10 } 11 12 int half = array.length/2; 13 for(int i = half; i >=0; i--){ 14 maxHeap(array, array.length, i); 15 } 16 } 17 18 //調整堆,使用沉降法實現大根堆 19 private static void maxHeap(int[] array, int heapSize, int index){ //利用沉降法調整堆 20 int left = index*2+1; 21 int right = index*2+2; 22 23 int largest = index; 24 if(left < heapSize && array[left] > array[largest]){ 25 largest = left; 26 } 27 28 if(right < heapSize && array[right] > array[largest]){ 29 largest = right; 30 } 31 32 if(largest != index){ //需要交換位置 33 int tmp = array[index]; 34 array[index] = array[largest]; 35 array[largest] = tmp; 36 37 maxHeap(array, heapSize, largest); 38 } 39 } 40 41 //堆排序算法 42 private static void heapSort(int[] array){ 43 if(array == null || array.length <= 1){ 44 return; 45 } 46 47 buildMaxHeap(array); 48 49 for(int i = array.length - 1; i > 0; i--){ 50 int tmp = array[0]; 51 array[0] = array[i]; 52 array[i] = tmp; 53 54 maxHeap(array, i, 0); 55 } 56 }? 插入排序? ?
? ? 直接插入排序
? ? ? ?思想:每次插入一個元素,保持前面子數組的有序性。
? ? ? ?穩定排序
? ?折半插入排序
? ? ? ?思想:將待排序的記錄R[i]插入到已經排序完成的記錄子表R[0,1,...i-1]中時,由于該子表已經排序完成,插找插入位置時可以使用"折半查找"實現。
穩定排序 希爾排序 思想:先將整個待排序的記錄序列分割成為若干子序列分別進行直接插入排序,待整個序列中的記錄“基本有序”時,再對全體記錄進行依次直接插入排序。? ??? ? ? ?1)選擇一個增量序列t1,t2,…,tk,其中ti>tj,tk=1;
? ? ? ?2)按增量序列個數k,對序列進行k 趟排序;
? ? ? ?3)每趟排序,根據對應的增量ti,將待排序列分割成若干長度為m的子序列,分別對各子表進行直接插入排序。僅增量因子為1 時,整個序列作為一個表來處理,表長度即為整個序列的長度。
不穩定排序 1 public int[] shellSort(int[] num, int len) { 2 // write code here 3 if(num == null || len < 2) 4 return num; 5 6 for(int step = len/2; step >= 1; step = step/2){ //選取希爾排序的間隔 7 subShellSort(num, step); 8 } 9 10 return num; 11 } 12 13 public void subShellSort(int[] num, int step){ 14 for(int i = step; i < num.length; i++){ 15 for(int j = i; j >=step; j-=step){ 16 if(num[j] < num[j-step]){ //利用冒泡排序進行子序列的排序 17 int tmp = num[j]; 18 num[j] = num[j-step]; 19 num[j-step] = tmp; 20 } 21 } 22 } 23 }?
歸并排序 ? ? ? 思想:將兩個(或兩個以上)有序表合并成一個新的有序表?即把待排序序列分為若干個子序列,每個子序列是有序的。然后再把有序子序列合并為整體有序序列?? ? ? 穩定排序
1 public class MergeSort { 2 public int[] mergeSort(int[] A, int n) { 3 // write code here 4 if(n<2){ 5 return A; 6 } 7 8 return sort(A,0,A.length-1); 9 10 } 11 12 public int[] sort(int[] num, int low, int high){ 13 int mid = (low+high)/2; 14 if(low < high){ 15 sort(num,low,mid); //排序左邊數組 16 17 sort(num,mid+1,high); //排序右邊數組 18 19 merge(num,low,mid,high); //歸并兩邊數組 20 } 21 22 return num; 23 } 24 25 public void merge(int[] num, int low, int mid, int high){ 26 int[] tmp = new int[high-low+1]; //建立臨時數組 27 int i = low, k = mid+1; //左右數組下標 28 int j = 0; 29 30 while(i<=mid && k<=high){ 31 if(num[i]<num[k]){ 32 tmp[j++] = num[i++]; 33 }else{ 34 tmp[j++] = num[k++]; 35 } 36 } 37 38 39 //左邊數組剩余元素 40 while(i <= mid){ 41 tmp[j++] = num[i++]; 42 } 43 44 //右邊數組剩余元素 45 while(k <= high){ 46 tmp[j++] = num[k++]; 47 } 48 49 //將新數組的值賦予num數組 50 for(int k1 = 0; k1<j; k1++){ 51 num[k1+low] = tmp[k1]; 52 } 53 54 } 55 }基數排序
? ?基數排序
? ? ? 思想:基數排序是一種非比較型整數排序算法,其原理是將整數按位數切割成不同的數字,然后按每個位數分別比較。由于整數也可以表達字符串(比如名字或日期)和特定格式的浮點數,所以基數排序也不是只能使用于整數。
? ?桶排序:
? ? ?思想:是將陣列分到有限數量的桶子里。每個桶子再個別排序(有可能再使用別的排序算法或是以遞回方式繼續使用桶排序進行排序)。桶排序是鴿巢排序的一種歸納結果。當要被排序的陣列內的數值是均勻分配的時候,桶排序使用線性時間(Θ(n))。但桶排序并不是比較排序,他不受到 O(n log n) 下限的影響。?
簡單來說,就是把數據分組,放在一個個的桶中,然后對每個桶里面的在進行排序。
? ? ? 穩定排序
轉載于:https://www.cnblogs.com/bywallance/p/6721647.html
總結
- 上一篇: 错误代码: 1054 Unknown c
- 下一篇: array_merge与array+ar