選擇排序,氣泡排序,插入排序
1.選擇排序
2.氣泡排序/雙向氣泡排序
3.插入排序
1.選擇排序
選擇排序是一種最為直觀的排序方法。每次迴圈從陣列中選擇出一個最小或者最大的元素,按順序重新放入陣列中,直到所有的戴排序元素都排序完成。
public void selectSort(int[] a){ int temp=0; for(int i=0;i<a.length-1;i++){ for(int j=i+1;j<a.length;j++){ if(a[j]<a[i]){ temp = a[j]; a[j] = a[i]; a[i] = temp; } } } }
從程式碼不難看出,選擇排序的過程是:第一次迴圈,遍歷陣列找出陣列中最小的數字,放入a[0],第二次迴圈,找出剩下陣列中最小的數字放入a[1]一次類推。
所以,選擇排序的時間複雜度為O(n^2),如果n較大,則效率會非常低。
2.氣泡排序
氣泡排序也是較為簡單的一種排序方法,之所以叫氣泡排序,是因為排序的手法會使數字浮到陣列頂端而得名。
氣泡排序的手法是:比較相鄰的兩個元素,如果相鄰的兩個元素的順序是錯誤的,則將他們交換;然後繼續比較下一組相鄰的元素。直到所有需要排列的元素都排序完成。
public void bubbSort(int[] a){ int temp=0; for(int i=0;i<a.length-1;i++){ for(int j=a.length-1;j>i;j--){ if(a[j]<a[j-1]){ temp = a[j]; a[j] = a[j-1]; a[j-1] = temp; } } } }
從程式碼我們可以看出來:氣泡排序是用層迴圈,外側迴圈的意義是在於,迴圈n次,每次冒泡都冒出最小的節點依次放在陣列的最前面。第二層迴圈的意義是在於,進行冒泡操作,每次比較相鄰的兩個元素,將較小的元素,像陣列頭方向移動。
因此我們可以看出氣泡排序的時間複雜度為O(n^2),如果n較大,則效率會非常低,如果陣列是有序的,即進行一次冒泡掃描發現移動的關鍵次數為最小時,說明陣列已經有序,此時的時間複雜度為O(n)。
雙向氣泡排序:
傳統的氣泡排序要麼是從左向右進行,要麼從右向左進行,每次都只對陣列一頭的元素進行掃描排序。
而雙向氣泡排序首先從前往後把最大數移到最後,然後反過來從後往前把最小的一個數移動到陣列最前面,這一過程就是第一輪,然後重複這一過程,最終就會把整個陣列從小到大排列好。
public void bubbSort2(int[] a){ int left =1 ; int right = a.length -1; int t=0; while(left<=right){ for(int i=right;i>=left;i--){ if(a[i]<a[i-1]){ int temp; temp = a[i]; a[i] = a[i-1]; a[i-1] = temp; t = i;//記錄上一次交換的下標 } } left = t+1; //t+1中間亂序部分的最左端 for(int i=left;i<right+1;i++){ if(a[i]<a[i-1]){ int temp; temp = a[i]; a[i] = a[i-1]; a[i-1] = temp; t = i;//記錄上一次交換的下標 } } right = t-1;//t-1為中間亂序部分的最右端 } }
從程式碼看來,雙向氣泡排序會比普通氣泡排序減少很多次迴圈。因為雙向排序時陣列的兩頭都排序好了,我們只需要處理陣列的中間部分即可,普通氣泡排序只有一頭的元素是排好序的。
雖然雙向氣泡排序有些改進,但是不能大幅度的提升效率,這是由於氣泡排序的基本過程所確定的。
3.插入排序
插入排序的基本方法是,每步將一個待排序的紀錄,按其關鍵碼值的大小插入前面已經排序的檔案中適當位置上,直到全部插入完為止。
public void insertSort(int[] a){ for(int i=1;i<a.length;i++){ int temp = a[i],j=i ; if(a[j-1]>temp){ while(j>=1&&a[j-1]>temp){//找到新元素合適的位置 a[j] = a[j-1];//前一個覆蓋後一個 j--; } } a[j]=temp; //插入元素 } }
直接插入排序最好的時間複雜度為O(n),平均時間複雜度為O(n^2)。同樣的,如果n過於大的時候,直接插入排序的效率會很低。
插入排序改進思路和氣泡排序一樣,我們也可以對於直接插入排序進行改進。在直接插入排序中我們每次插入元素的時候,都是挨個遍歷前面所有元素,這樣遍歷的效率並不高。
因為插入的陣列是已經排好序的有序陣列,所以我們自然而然的想到了折半插入的方法,這樣可以減少比較的次數。
不過雖然折半插入會減少元素比較的次數,但因為是插入陣列,所以,只是減少元素的比較次數,元素移動的個數依然沒有改變,時間複雜度依然是O(n^2)。