【問題描述】
假設需要我們在一堆海量資料中找出排名前k的資料;最好的方法是用最小堆排序,直接用前k個資料建立乙個小頂堆,然後遍歷剩餘的數,
②如果此數》堆頂的數,則將此數和堆頂的數交換,然後從堆頂向下調整堆,使其重新滿足小頂堆。
【說明】堆的儲存
一般用陣列來表示堆,第i個節點的父節點下標為i/2-1;它的左右節點下標分別為:2*i+1和2*1+2
【**】
一、從第i個點向下調整堆的過程
// 從i節點開始向下調整,n為節點總數,從i開始計算 i節點的子節點為 2*i+1, 2*i+2
void minheapdown(int a, int i, int n)
a[i] = temp;
}
二、建立最小堆的過程
【說明】從最後乙個非葉節點開始,追個進行向下調整操作,保證當前節點的所有子節點是滿足最小堆的,然後一直到根節點,保證這個堆是滿足小頂堆的
//建立最小堆
void makeminheap(int a, int n)
三、當來乙個新數,需要替換堆頂元素時,替換堆頂元素,然後,從堆頂元素向下進行一次調整,即可使新堆滿足小頂堆
//如果當前值key>堆頂元素,則進行替換操作,然後進行向下調整
void minheapreplaceheader(int a, int n,int key)
四、遍歷完所有資料後,最後剩餘在k個節點的小頂堆中的資料即我們所求的top-k;從堆頂進行挨個刪除【堆頂和最後乙個元素替換,進行輸出】;然後重新向下調整堆,直到所有資料都輸出完,結束
void minheapdeletenumber(int a, int n)
//進行遍歷,輸出最終k個值的過程
for(int i=n-1;i>=0;i--)
printf("%d ",a[i]);
}
堆排序的時間複雜度為o(n*logn)
【話外音】
當然,若資料不是很大,也可以用快排先進行排序,然後直接輸出前k個最大的數;資料量大的情況下,不提倡排序
堆排序以及TopK大頂堆小頂堆求解方式(js版)
堆排序是一種選擇排序,時間複雜度o nlogn 空間複雜度o 1 資料結構底層是陣列,通過索引之間的關係可看二叉樹,父結點總是大於或者小於孩子結點。這就是堆的結構。剛初始完的堆是佔據整個陣列的。開始排序後,陣列分為兩個部分!前面是堆,後面是已排序完的有序子陣列。排序時,堆頂元素和堆尾元素會交換,有序...
排序演算法 堆排序(大頂堆 小頂堆)
堆排序的思想這裡就先不講了,以後有時間再補上,下面是分別採用大頂堆和小頂堆實現的堆排序。注意 下面例子中排序的數字是。大頂堆方式 include include using namespace std 堆調整 將nums s.m 調整為大頂堆,其中除了nums s 之外均滿足大頂堆的定義 void ...
Java 堆排序 大頂堆 小頂堆
引用 堆排序 heapsort 是指利用堆這種資料結構所設計的一種排序演算法。堆積是乙個近似完全二叉樹的結構,並同時滿足堆積的性質 即子結點的鍵值或索引總是小於 或者大於 它的父節點。堆排序的平均時間複雜度為 nlogn 演算法步驟 1.建立乙個堆h 0.n 1 2.把堆首 最大值 和堆尾互換 3....