冒泡排序:
在概念上是排序算法中最簡單的,但是運行起來非常慢,冒泡排序遵循以下幾個規則(假如我們現在要給一隊打亂的足球隊員排序):
- 比較兩個隊員
- 如果左邊的隊員比右邊的高,則交換位置
- 向右移動一位,比較下面兩個隊員
接下來給出冒泡排序的JAVA代碼
1 public Integer[] bubbleSort(Integer[] a){ 2 int out,in; 3 for(out = a.length-1;out > 0;out--){//外層每循環一次排出一個最大值 4 for(in = 0;int < out;in++){ 5 if(a[in]>a[in+1]){ //比較相鄰元素大小,左邊的大則交換位置 6 long temp = a[in]; 7 a[in] = a[in+1]; 8 a[in+1] = temp; 9 } 10 } 11 } 12 return a; 13 }
冒泡排序的效率:
在冒泡排序中若有N個數據項,則第一趟排序中需要N-1次比較,第二趟中有N-2次比較,類推下來我們可以得到比較次數的求和公式N*(N-1)/2這樣我們忽略-1可得我們的冒泡算法大概做了N2/2次比較,假設數據是隨機的,則需要進行交換的次數平均下來是N2/4次。交換和比較的操作次數都和N2成正比,在大O表示法中,冒泡排序運行需要O(N2)的時間級別,在任何時候只要看到一個循環嵌套在另外一個循環中我們都可以懷疑他的運行時間為O(N2)級別;
選擇排序:
選擇排序改進了冒泡排序,將必要的交換次數從O(N2)減少到了O(N)但是比較次數仍然是O(N2),選擇排序算法,假如對一隊足球隊員進行排序,從隊列的最左端開始記錄隊員的身高,和后面的隊員挨個比較,若遇到身高比他矮的,則記錄換成更矮的人的身高,最后這一趟排序就能找到最矮的隊員,然后最后再和第一個隊員進行交換位置;這期間做了N-1次比較,只做了一次交換;下面給出排序的java代碼
public Integer[] selectionSort(Integer[] a){ int out, in, min; for (out = 0; out < a.length-1; out++) { min = out; //記錄最小元素的索引 for (in = out + 1; in < a.length; in++) { if (a[min] > a[in]) { //依次比較記錄較小元素的索引 min = in; } } //上面循環結束得到此外層循環的最小元素,進行交換 int temp = a[min]; a[min] = a[out]; a[out] = temp; } return a; }
選擇排序的效率:
選擇排序和冒泡排序執行了相同的比較次數N*(N-1)/2。當N值很大的時候,比較的次數是主要的,所以選擇排序運行的時間用大O法表示為O(N2),雖然大O表示復雜度和冒泡一樣,但是選擇排序無疑是更快的,因為進行的交換要少很多,當N值較小時,特別是交換時間比比較時間大得多的時候,選擇排序無疑是相當快的。
插入排序:
大多情況下插入排序是基本排序算法中最好的一種,雖然用大O表示時間復雜度仍然為O(N2),但是一般情況下比冒泡排序快一倍,比選擇排序還要快一點。經常用在比較復雜的排序的最后階段,比如快速排序。
插入排序算法即從隊列最左邊開始,將后面的每個人一個個地插入到隊列的相應的位置,
上圖可以很好地表示排序算法的排序過程,對於上圖的理解,假如我們從排序算法的中間開始,在被標記的隊員左邊已經排好序了,此時讓已標記的隊員出列,然后依次同左邊的隊員比較,將比標記隊員高的依次向右移,最后找到需要插入的位置,插入標記的隊員,下面給出插入排序java代碼
1 public Integer[] insertionSort(Integer[] a){ 2 int out, in; 3 4 for (out = 1; out < a.length; out++) { 5 int temp = a[out]; 6 in = out; 7 while (in > 0 && a[in - 1] >= temp) { 8 a[in] = a[in - 1]; //每個比當前標記的大的元素一次向數組后移一位 9 --in; 10 } 11 //當上面的循環結束時,此時in的位置就剛好停在比當前標記元素大的前面一個位置 12 //此時位置經過循環之后所有比標記元素大的都向后移動過了,因此此時可以向當前位置插入元素 13 a[in] = temp; 14 } 15 return a; 16 }