雖然排序算法爛大街了,可是哥依然用java實現了一遍,只爲本身練練手,後面能夠時不時的回頭看看。。。僅此而已,各位能夠提意見,莫噴!!html
1、冒泡排序java
基本思想:在要排序的一組數中,對當前還未排好序的範圍內的所有數,自上而下對相鄰的兩個數依次進行比較和調整,讓較大的數往下沉,較小的往上冒。即:每當兩相鄰的數比較後發現它們的排序與排序要求相反時,就將它們互換git
1 /** 2 * 冒泡排序 3 * @param data 要排序的數組 4 * @param reverse 從大到小(false)仍是從小到大(ture) 5 */ 6 public static void sort(int[] data, boolean reverse) { 7 if (data.length == 1) { 8 return; 9 } 10 for (int i = 0; i < data.length - 1; i++) { 11 int tmp = 0; 12 for (int j = 0; j < data.length - i - 1; j++) { 13 if (reverse) { //從小到大(ture) 14 if (data[j] >= data[j+1]) { 15 tmp = data[j]; 16 data[j] = data[j +1 ]; 17 data[j+1] = tmp; 18 } 19 } else { //從大到小(false) 20 if (data[j] <= data[j+1]) { 21 tmp = data[j+1]; 22 data[j+1] = data[j]; 23 data[j] = tmp; 24 } 25 } 26 } 27 } 28 }
2、堆排序github
基本思想:堆排序是一種樹形選擇排序,是對直接選擇排序的有效改進。算法
堆的定義以下:具備n個元素的序列(h1,h2,...,hn),當且僅當知足(hi>=h2i,hi>=2i+1)或(hi<=h2i,hi<=2i+1)(i=1,2,...,n/2)時稱之爲堆。在這裏只討論知足前者條件的堆。由堆的定義能夠看出,堆頂元素(即第一個元素)必爲最大項(大頂堆)。徹底二叉樹能夠很直觀地表示堆的結構。堆頂爲根,其它爲左子樹、右子樹。初始時把要排序的數的序列看做是一棵順序存儲的二叉樹,調整它們的存儲序,使之成爲一個堆,這時堆的根節點的數最大。而後將根節點與堆的最後一個節點交換。而後對前面(n-1)個數從新調整使之成爲堆。依此類推,直到只有兩個節點的堆,並對它們做交換,最後獲得有n個節點的有序序列。從算法描述來看,堆排序須要兩個過程,一是創建堆,二是堆頂與堆的最後一個元素交換位置。因此堆排序有兩個函數組成。一是建堆的滲透函數,二是反覆調用滲透函數實現排序的函數 數組
1 /** 2 * 堆排序 3 * @param data 要排序的數組 4 * @param reverse 從大到小(false)仍是從小到大(ture) 5 */ 6 public static void sort(int[] data, boolean reverse) { 7 if (data.length == 1) { 8 return; 9 } 10 for (int i = 0; i < data.length; i++) { 11 //建堆 12 buildHeap(data, 0, data.length -1 - i, reverse); 13 int tmp = data[0]; 14 data[0] = data[data.length - 1 - i]; 15 data[data.length - 1 - i] = tmp; 16 } 17 } 18 19 /** 20 * 將指定開始和結束段的數據建堆 21 * @param data 22 * @param beginIndex 23 * @param endIndex 24 * @param reverse 25 */ 26 public static void buildHeap(int[] data, int beginIndex, int endIndex, boolean reverse) { 27 if (beginIndex >= endIndex) { 28 return; 29 } 30 for (int i = (endIndex + beginIndex - 1) / 2; i >= beginIndex; i--) { 31 int cur = i; 32 if (reverse) { //大頂堆,用來從小到大排序 33 //發生交換以後須要檢查孫子節點,重孫子節點... 34 while (2 * cur + 1 <= endIndex) { 35 int biggerChildIndex = 2 * cur + 1; 36 if (biggerChildIndex + 1 <= endIndex) { 37 if (data[biggerChildIndex] < data[biggerChildIndex + 1]) { 38 biggerChildIndex = biggerChildIndex + 1; 39 } 40 } 41 //找到最大子節點,若是比當前節點大,就交換 42 if (data[i] < data[biggerChildIndex]) { 43 int tmp = data[i]; 44 data[i] = data[biggerChildIndex]; 45 data[biggerChildIndex] = tmp; 46 //準備檢查孫子節點 47 cur = biggerChildIndex; 48 } else { 49 break; 50 } 51 } 52 } else { //小頂堆,用來從大到小排序 53 //發生交換以後須要檢查孫子節點,重孫子節點... 54 while (2 * cur + 1 <= endIndex) { 55 int samllerChildIndex = 2 * i + 1; 56 if (samllerChildIndex + 1 <= endIndex) { 57 if (data[samllerChildIndex] > data[samllerChildIndex + 1]) { 58 samllerChildIndex = samllerChildIndex + 1; 59 } 60 } 61 //找到最小子節點,若是比當前節點小,就交換 62 if (data[i] > data[samllerChildIndex]) { 63 int tmp = data[i]; 64 data[i] = data[samllerChildIndex]; 65 data[samllerChildIndex] = tmp; 66 cur = samllerChildIndex; 67 } else { 68 break; 69 } 70 } 71 } 72 } 73 }
3、直接插入排序ide
基本思想:在要排序的一組數中,假設前面(n-1)[n>=2]個數已是排好順序的,如今要把第n個數插到前面的有序數中,使得這n個數也是排好順序的。如此反覆循環,直到所有排好順序。函數
1 /** 2 * 插入排序 3 * @param data 要排序的數組 4 * @param reverse 從大到小(false)仍是從小到大(ture) 5 */ 6 public static void sort(int[] data, boolean reverse) { 7 if (data.length == 1) { 8 return; 9 } 10 int tmp = 0; 11 for (int i = 1; i < data.length; i++) { 12 tmp = data[i]; 13 int n = i - 1; 14 for (; n >= 0; n--) { 15 if (reverse) { //從小到大排序 16 if (data[n] >= tmp) { 17 data[n + 1] = data[n]; //將大於當前值的數後移一個位置 18 } else { 19 break; 20 } 21 } else { //從大到小排序 22 if (data[n] <= tmp) { 23 data[n + 1] = data[n]; //將小於當前值的數後移一個位置 24 } else { 25 break; 26 } 27 } 28 } 29 data[n+1] = tmp; 30 } 31 }
4、歸併排序ui
基本思想:歸併(Merge)排序法是將兩個(或兩個以上)有序表合併成一個新的有序表,即把待排序序列分爲若干個子序列,每一個子序列是有序的。而後再把有序子序列合併爲總體有序序列。 spa
1 /** 2 * 歸併排序 3 * @param data 要排序的數組 4 * @param reverse 從大到小(false)仍是從小到大(ture) 5 */ 6 public static void sort(int[] data, int left, int right, boolean reverse) { 7 if (left >= right) { 8 return; 9 } 10 int mid = (left + right) / 2; 11 sort(data, left, mid, reverse); 12 sort(data, mid + 1, right, reverse); 13 merge(data, left, mid, right, reverse); 14 } 15 16 /** 17 * 合併已排序好的兩段 18 * @param data 19 * @param left 20 * @param mid 21 * @param right 22 * @param reverse 23 */ 24 public static void merge(int[] data, int left, int mid, int right, boolean reverse) { 25 int[] tmp = new int[right - left + 1]; 26 int i = left; 27 int j = mid + 1; 28 int n = 0; 29 while (i <= mid && j <= right) { 30 if (reverse) { //從小到大 31 if (data[i] <= data[j]) { 32 tmp[n++] = data[i++]; 33 } else { 34 tmp[n++] = data[j++]; 35 } 36 } else { //從大到小 37 if (data[i] <= data[j]) { 38 tmp[n++] = data[j++]; 39 } else { 40 tmp[n++] = data[i++]; 41 } 42 } 43 } 44 while (i <= mid) { 45 tmp[n++] = data[i++]; 46 } 47 while (j <= right) { 48 tmp[n++] = data[j++]; 49 } 50 for (int k = 0; k < tmp.length; k++) { 51 data[left + k] = tmp[k]; 52 } 53 }
5、快遞排序
基本思想:選擇一個基準元素,一般選擇第一個元素或者最後一個元素,經過一趟掃描,將待排序列分紅兩部分,一部分比基準元素小,一部分大於等於基準元素,此時基準元素在其排好序後的正確位置,而後再用一樣的方法遞歸地排序劃分的兩部分
1 /** 2 * 快速排序 3 * @param data 4 * @param left 5 * @param right 6 * @param reverse 從大到小(false)仍是從小到大(ture) 7 */ 8 public static void sort(int[] data, int left, int right, boolean reverse) { 9 if (left >= right) { 10 return; 11 } 12 int index = getIndex(data, left, right, reverse); 13 sort(data, left, index - 1, reverse); 14 sort(data, index + 1, right, reverse); 15 } 16 17 /** 18 * 將待排序片斷調整順序,得到"中間數據"的正確索引 19 * @param data 20 * @param left 21 * @param right 22 * @param reverse 從大到小(false)仍是從小到大(ture) 23 * @return 24 */ 25 public static int getIndex(int[] data, int left, int right, boolean reverse) { 26 int cur = data[left]; 27 int i = left; 28 int j = right; 29 while (i < j) { 30 if (reverse) { //從小到大 31 while (data[j] > cur && i < j) { 32 --j; 33 } 34 data[i] = data[j]; 35 while (data[i] <= cur && i < j) { 36 ++i; 37 } 38 data[j]=data[i]; 39 } else { //從大到小 40 while (data[j] < cur && i < j) { 41 --j; 42 } 43 data[i]=data[j]; 44 while (data[i] >= cur && i < j) { 45 ++i; 46 } 47 data[j]=data[i]; 48 } 49 } 50 data[i] = cur; 51 return i; 52 }
6、基數排序
基本思想:將全部待比較數值(正整數)統一爲一樣的數位長度,數位較短的數前面補零。而後,從最低位開始,依次進行一次排序。這樣從最低位排序一直到最高位排序完成之後,數列就變成一個有序序列。
1 /** 2 * 基數排序 3 * @param data 要排序的數組 4 * @param reverse 從大到小(false)仍是從小到大(ture) 5 */ 6 public static void sort(int[] data, boolean reverse) { 7 if (data.length == 1) { 8 return; 9 } 10 int max = 0; 11 for (int i = 0; i < data.length; i++) { //找出最大的數據 12 if (max < data[i]) { 13 max = data[i]; 14 } 15 } 16 System.out.println("the max number is :" + max); 17 int radix = 1; 18 ArrayList<ArrayList<Integer>> numbers = new ArrayList<ArrayList<Integer>>(10); 19 for (int i = 0; i < 10; i++) { 20 numbers.add(i, new ArrayList<Integer>()); 21 } 22 while (max > radix) { 23 for (int i = 0; i < data.length; i++) { 24 int index = (data[i] / radix) % 10; 25 ArrayList<Integer> list = numbers.get(index); 26 list.add(data[i]); 27 numbers.set(index, list); 28 } 29 resetOrder(data, numbers, reverse); 30 radix = radix * 10; 31 } 32 } 33 34 /** 35 * 從新調整數組順序 36 * @param data 37 * @param numbers 38 * @param reverse 從大到小(false)仍是從小到大(ture) 39 */ 40 public static void resetOrder(int[] data, ArrayList<ArrayList<Integer>> numbers, boolean reverse) { 41 int n = 0; 42 if (reverse) { 43 for (int i = 0; i < numbers.size(); i++) { 44 ArrayList<Integer> list = numbers.get(i); 45 while(list.size()>0){ 46 data[n++] = list.get(0); 47 list.remove(0); 48 } 49 } 50 } else { 51 for (int i = numbers.size() - 1; i >= 0; i--) { 52 ArrayList<Integer> list = numbers.get(i); 53 while(list.size()>0){ 54 data[n++] = list.get(0); 55 list.remove(0); 56 } 57 } 58 } 59 }
7、選擇排序
基本思想:在要排序的一組數中,選出最小的一個數與第一個位置的數交換;而後在剩下的數當中再找最小的與第二個位置的數交換,如此循環到倒數第二個數和最後一個數比較爲止。
1 /** 2 * 選擇排序 3 * @param data 要排序的數組 4 * @param reverse 從大到小(false)仍是從小到大(ture) 5 */ 6 public static void sort(int[] data, boolean reverse) { 7 if (data.length == 1) { 8 return; 9 } 10 for(int i=0;i<data.length-1;i++){ 11 int tmp=data[i]; //要初始化 12 int index = i; //要初始化 13 for(int j=i;j<data.length;j++){ 14 if(reverse) { //從小到大(ture) 15 if (tmp>=data[j]){ 16 tmp = data[j]; //最小值 17 index = j; 18 } 19 }else { 20 if (tmp<=data[j]){ 21 tmp = data[j]; //最大值 22 index = j; 23 } 24 } 25 } 26 data[index] = data[i]; 27 data[i] = tmp; 28 } 29 }
8、希爾排序
基本思想:算法先將要排序的一組數按某個增量d(n/2,n爲要排序數的個數)分紅若干組,每組中記錄的下標相差d.對每組中所有元素進行直接插入排序,而後再用一個較小的增量(d/2)對它進行分組,在每組中再進行直接插入排序。當增量減到1時,進行直接插入排序後,排序完成。
1 /** 2 * 希爾排序 3 * @param data 要排序的數組 4 * @param reverse 從大到小(false)仍是從小到大(ture) 5 */ 6 public static void sort(int[] data, boolean reverse) { 7 if (data.length == 1) { 8 return; 9 } 10 for (int d = data.length / 2; d >= 1; d = d / 2) { //組大小 11 for (int k = 0; k < d; k++) { //多少組 12 for (int n = d + k; n < data.length; n = n + d) { //同一組 13 int cur = n; 14 while (cur - d >= 0) { //插入排序 15 int tmp = 0; 16 if (reverse) { //小到大(ture) 17 if (data[cur] <= data[cur - d]) { 18 tmp = data[cur]; 19 data[cur] = data[cur - d]; 20 data[cur - d] = tmp; 21 } 22 } else { //從大到小(false) 23 if (data[cur] >= data[cur - d]) { 24 tmp = data[cur]; 25 data[cur] = data[cur - d]; 26 data[cur - d] = tmp; 27 } 28 } 29 cur = cur - d; 30 } 31 } 32 } 33 } 34 35 }
相關的資料大夥能夠自行尋找,本文就不詳細介紹了。。。 都爛大街了。。。
如下是一些不錯的相關文章
參考:
1.http://blog.csdn.net/qy1387/article/details/7752973#0-tsina-1-35851-397232819ff9a47a7b7e80a40613cfe1
2.http://www.cnblogs.com/luxiaoxun/archive/2012/09/01/2666677.html
3.http://www.cnblogs.com/yefengmeander/archive/2008/12/05/2887903.html
4.http://blog.jobbole.com/79288/
5.https://github.com/ztgu/sorting_algorithms_py
就當本身回顧知識了