本文包括:
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)。