數據結構與算法之排序算法(三):選擇排序

選擇排序能夠分爲:簡單選擇排序和堆排序(已知位置,找元素)
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];
        }
    //先將排序的序列構建成一個大頂堆
    forint 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】 優勢:因爲構建堆花的時間比較多,因此適應於大數據量排序 spa

相關文章
相關標籤/搜索