標籤:空間 class heapsort 調整 賦值 構建 swap pre 優點
選擇排序可以分為:簡單選擇排序和堆排序(已知位置,找元素)1.簡單選擇排序
原理:就是直接從待排序數組裡選擇一個最小(最大)的數字,順序放入數組裡,直到數組排好序
代碼實現:
for(int i=0;i<a.length-1;i++){ int smallest = i; for(int j=i+1;j<a.length;j++){ if(a[j] < a[smallest]){ smallest = j; } } if(smallest != i){ a[i] = a[i] ^ a[smallest]; a[smallest] = a[i] ^ a[smallest]; a[i] = a[i] ^ a[smallest]; }}
分析:演算法不穩定(比如:5,2,5,1.第一個5會和1交換),空間複雜度O(1),時間複雜度【最佳,平均和最差O(n*n)】
2.堆排序(簡單選擇排序的改進)
原理:將待排序的序列構造成一個大頂堆。此時,整個序列的最大值就是堆頂的根節點。將它移走(其實就是講其與堆數組中的末尾元素交換,此時末尾元素就是最大值),然後將剩餘n-1個序列重新構成一個堆,這樣就會得到n個元素中的次大值。如此反覆執行,便能得到一個有序序列了。
代碼實現:
void heapSort(array[] a){ 將數組向後移動一位,使得元素序號從1開始 int[] arr = new int[a.length + 1]; for (int i = 0; i < a.length; i++ ){ arr[i+1] = a[i]; } //先將排序的序列構建成一個大頂堆 for(int i = a.length / 2; i > 0; i--){ heapAdjust(arr, i, a.length); } //排序 for(int j = a.length; j > 1; j--){ swap(arr,1,j);//將堆頂元素和當前未經排序的子序列的最後一個元素交換 heapAdjust(arr,1,j-1);//將剩下n-1個序列重新構建成大頂堆 } //將排好序的序列複製到原數組 for (int i = 0; i < a.length; i++ ){ a[i] = arr[i+1]; }}void heapAdjust(array[] a, int i, int n){ int tmp = a[i];//將待調整序列的根節點臨時儲存 for(int j = 2 * i; j <= n; j *= 2){//對元素較大的孩子節點向下篩選 if(j < n && a[j] < a[j+1]){//將j指向元素較大的孩子 ++j; } if(tmp <= a[j]){//如果根節點小於孩子中最大的元素,則將孩子中最大的元素賦值給根節點 a[i] = a[j]; }else{break;} i = j;//將j作為根節點,繼續調整它的子節點 } a[i] = tmp;//將根節點的值賦值給調整後的子節點}
分析:不穩定,空間代價O(1),時間複雜度【最好、平均、最差均為nlogn】 優點:由於構建堆花的時間比較多,所以適應於大資料量排序
資料結構與演算法之排序演算法(三):選擇排序