topk 堆排序 小頂堆

2021-07-14 22:00:12 字數 1214 閱讀 8163

【問題描述】

假設需要我們在一堆海量資料中找出排名前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....