排序 堆排序

2021-08-29 05:21:58 字數 1625 閱讀 9016

在簡單選擇排序中,我們每一趟都要選擇乙個極值元素。那麼在第一趟選擇極值元素時,能否多做些工作,為後面選擇極值元素帶來便利呢?下面介紹一下堆排序。

首先看一下什麼是堆:

滿足下列性質的序列稱為堆:

小頂堆:

ri <= r2i;

ri <= r(2i+1)

如:大頂堆:

ri >= r2i;

ri >= r(2i+1).

如:堆的性質:小頂堆對應的完全二叉樹任意結點均比孩子小或相等。大頂堆對應的完全二叉樹中任意結點均比其孩子大或相等。

小頂堆堆頂元素最小,大頂堆堆頂最大,子樹也是堆。

基本思想:利用堆每次選擇出最大交換到隊尾。

輸入:順序表的長度,順序表中各個元素。

輸出:排好序的順序表中各個元素。

執行結果:

具體方法:

先建初始大頂堆;

堆頂與堆尾互換(最大記錄換到最後);忽略堆尾,將前n-1個記錄組成的樹重新調整為大頂堆(篩選)。

重複上一步n-1趟 即可。

輔助巨集:

#define ok 1

#define error 0

#define true 1

#define false 0

#define overflow -1

#define null 0

typedef char *infotype;

typedef int keytype; //設關鍵字為整型

順序表儲存結構定義:

typedef struct

redtype;

//順序表的儲存結構定義

typedef struct

sqlist;

首先我們來看一下如何篩選:

篩選即對一顆左/右子樹均為堆的完全二叉樹,調整根結點使整個二叉樹也稱為乙個堆。

方法:備份堆頂,比較堆頂與其兩個孩子,若堆頂不最大則將兩孩子中的大者上移,之後的子樹可能不再是堆。重複上述操作至最後(當前堆頂大於等於孩子或無孩子)。

typedef sqlist heaptype; //採用順序表儲存堆
void heapadjust(heaptype &h,int s,int m)

}//經此迴圈則比rc大的均上移 ,s指向待插入位置

redcopy(h.r[s],rc);

}

建造初始大頂堆:從最後乙個非葉子結點開始向根結點方向逐步調整建堆。

完整實現:

void heapsort(heaptype &h)

}

演算法分析:

最壞時間複雜度:o(n*logn)

選出最大的乙個,比選擇排序慢,為啥還好呢?

建初始大頂堆比簡單選擇排序慢了,複雜度變成了o(n*logn)。但是,構造的樹在後面提高了找極值元素的效率。

僅用乙個記錄輔助空間rc

該演算法是一種不穩定的演算法。優化餘地小。

正序時最慢,適合n大且雜亂。

堆排序 堆排序優化 索引堆排序

堆排序 堆排序優化 索引堆排序 注 堆排序 索引堆排序 都是不穩定的排序。注 索引最大堆排序有誤!有沒有大神可以指點一二?1 堆 所有元素 都從索引0開始 父親結點索引 i 左孩子結點索引 2i 1 右孩子結點索引 2i 2 左後乙個非葉子結點索引 n 1 2 用於構建堆,從最後乙個非葉子結點索引開...

堆排序 堆排序優化 索引堆排序

堆排序 堆排序優化 索引堆排序 注 堆排序 索引堆排序 都是不穩定的排序。注 索引最大堆排序有誤!有沒有大神可以指點一二?1 堆 所有元素 都從索引0開始 父親結點索引 i 左孩子結點索引 2i 1 右孩子結點索引 2i 2 左後乙個非葉子結點索引 n 1 2 用於構建堆,從最後乙個非葉子結點索引開...

堆排序 模擬堆排序

838.堆排序 輸入乙個長度為n的整數數列,從小到大輸出前m小的數。輸入格式 第一行包含整數n和m。第二行包含n個整數,表示整數數列。輸出格式 共一行,包含m個整數,表示整數數列中前m小的數。資料範圍 1 m n 1051 m n 105,1 數列中元素 1091 數列中元素 109 輸入樣例 5 ...