八大常見內排序java實現

  雖然排序算法爛大街了,可是哥依然用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     }
View Code

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     }
View Code

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     }
View Code

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     }
View Code

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     }
View Code

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     }
View Code

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     }
View Code 

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     }
View Code

 

相關的資料大夥能夠自行尋找,本文就不詳細介紹了。。。 都爛大街了。。。

如下是一些不錯的相關文章

參考:

  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

 

就當本身回顧知識了

相關文章
相關標籤/搜索