排序目的:便於查詢。
排序演算法好壞的衡量指標:時間效率(時間複雜度、比較次數),空間效率(空間複雜度、佔記憶體輔助空間大小),穩定性(關鍵字值相等的記錄a和b在排序後先後次序不變則穩定)
內部排序概念:待排序記錄都在記憶體中。
外部排序概念:待排序記錄一部分在記憶體,一部分在外存(硬碟等)。
按排序規則不同分為:
插入排序
交換排序
選擇排序
歸併排序
基數排序
按時間複雜度不同分為:
簡單排序 o(n2)
先進排序 o(nlog2n)
基數排序 o(d*n) ——其中d=關鍵字的位數
因為最近在刷leetcode的時候多次遇到使用堆排序解決的題目,所以特別寫在筆記裡,一勞永逸。
堆排序是由2023年的計算機先驅獎獲得者、史丹福大學電腦科學系教授羅伯特.弗洛伊德(robert w.floyd)和威廉士(j.williams)在2023年共同發明了的一種排序演算法( heap sort );
概念:大頂堆和小頂堆(也叫大根堆和小根堆)。
定義:堆的定義:設有n個元素的序列 k1,k2,…,kn,當且僅當滿足下述關係之一時,稱之為堆。
大頂堆:
當用一位陣列儲存這個序列,就是在乙個完全二叉樹中,所有父節點比它的子節點都要大。根節點的值最大。
小頂堆:(略)
方法描述:設有n個元素,將其按關鍵碼排序。首先將這n個元素按關鍵碼建成堆,將堆頂元素輸出,得到n個元素中關鍵碼最小(或最大)的元素。然後,再對剩下的n-1個元素建成堆,輸出堆頂元素,得到n個元素中關鍵碼次小(或次大)的元素。如此反覆,便得到乙個按關鍵碼有序的序列。稱這個過程為堆排序。
概括:
1.先對元素序列整理成堆。
2.將首尾元素互換位置,即交換完全二叉樹中根節點與最後乙個葉子節點之間的位置。
3.將剩下的n-1個元素視為乙個完全二叉樹並整理成堆。以此迴圈,直到二叉樹只剩乙個根節點。
需要解決的問題有兩個:
1.將n個元素的序列整理成堆。
2.調整後n-1個元素的序列整理成堆。
(思考1:為什麼要建堆?要排序的話,每次把最大或者最小值找到並拎出來不就好了嗎?為什麼要把整體結構都弄成堆的格式?)
問題1 初始建堆方法(以建大根堆為例):
問題2 剩餘元素重新建堆思考
複雜度計算
這裡引用其他網友的部落格內容,位址為
(前兩天自己試著算了一次弄明白過了,現在總結的時候就不再花時間算了)
概括:空間複雜度o(1),因為是就地排序。
時間複雜度包括兩部分,乙個是初始建堆乙個是後續的n輪堆化。
初始建堆:o(n)
n輪重新堆化:o(nlog2n)
所以總時間複雜度 = o(n)+o(nlog2n) = o(nlog2n)
應用來自領扣,初級演算法題,陣列類。
題目:給定乙個整數陣列,判斷是否存在重複元素。
如果任意一值在陣列**現至少兩次,函式返回 true 。如果陣列中每個元素都不相同,則返回 false 。
解法:先排序(堆排序),在挨個比較。
**:
public
class
solution
return
false;}
void
heapadjust
(int
nums,
int s,
int m)}}
void
heapsort
(int
nums,
int n)
}}
資料結構 排序(堆排序)
最小堆的特性說明 即任何一非葉節點的值不大於其左右孩子節點的值。堆排序最適合取topn的資料 include myheap.h int myswap int src,int desc 調整樹 arr 需要排序的陣列 root 根節點 size 樹的大小 int changetree int arr,...
資料結構 排序 堆排序
附加空間 乙個儲存最大記錄的空間 是否是穩定的排序方法 不穩定 include stdio.h define maxsize 10 typedef int keytype typedef struct recordtype typedef struct table void swap table t...
資料結構 排序 堆排序
堆排序是選擇排序中的一種,選擇排序的思想是在未排序的數列中選擇乙個最大或者最小的資料加入已排序序列,大根堆這個結構的根節點就是最大值,因此會大大方便選擇。在完全二叉樹中,根 左,右 手動建堆 第一步 順序建立一棵樹 第二步 檢查非葉子結點是否滿足 根 左,右,不滿足就將當前節點與最大的乙個孩子互換 ...