堆排序

堆的基本概念

堆是將一個序列看成完全二叉樹,意思就是說將一個序列看成是二叉樹的順序結構,而且這個順序結構沒有空節點,常見的考法是判斷一個序列是否是一個堆(大根堆或小根堆),大根堆和小根堆的定義如下:

  • 小根堆 : 所有的根節點小於所有子節點(如果子節點存在),即$K[i]\leq K[2i]$且$K[i]\leq K[2i+1]$
  • 大根堆 : 所有的根節點大於所有子節點(如果子節點存在),即$K[i]\geq K[2i]$且$K[i]\geq K[2i+1]$

堆排序

調整算法

堆排序實際上是不斷將一個堆上的根結點彈出,因爲根節點總是最大的或者最小的,只要彈出後不斷建成新的堆即可,建堆時間利用的就是調整算法.調整算法有如下特點:

  • 從第一個非葉子節點開始調整
  • 如果調整的非葉子節點的子節點也是非葉子節點,那麼子樹還要調整,因爲調整後可能破環子樹的堆狀態.

代碼:

void sift(int *seq,int low,int high) {
    int i = low;
    int j = 2*i;
    int temp = seq[i];
    while(j<=high) {
        if(j<high&&seq[j]<seq[j+1]) {
            j = j+1;
        }
        if(temp<seq[j]) {
            seq[i] = seq[j];
            i = j;
            j = 2*i;
        } else {
            break;
        }
    }
    seq[i] = temp;
}

排序算法

堆排序算法示例:

#include <iostream>

using namespace std;

void sift(int *seq,int low,int high) {
    int i = low;
    int j = 2*i;
    int temp = seq[i];
    while(j<=high) {
        if(j<high&&seq[j]<seq[j+1]) {
            j = j+1;
        }
        if(temp<seq[j]) {
            seq[i] = seq[j];
            i = j;
            j = 2*i;
        } else {
            break;
        }
    }
    seq[i] = temp;
}

int main() {
    int seq[10] = {6,8,7,9,0,1,3,2,4,5};
    for(int i=4; i>=0; i--) {
        sift(seq,i,9);
    }
    for(int i=0; i<10; i++) {
        cout<<seq[i]<<" ";
    }
    cout<<"\n";
    for(int i=0; i<10; i++) {
        cout<<seq[0]<<" ";
        seq[0] = seq[9-i];
        sift(seq,0,9-i);
    }

}
??正文結束??
發佈了153 篇原創文章 · 獲贊 16 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章