1. 程式人生 > >大小堆排序 & Top K 問題

大小堆排序 & Top K 問題

大小堆排序

堆這種資料結構定義比較簡單,大根堆就是父節點的值大於左右子孩子節點的值(小根堆相反),而且利用陣列下標就可以很好的表現堆(不過要注意是從0 還是 1開始)。堆常用語實現優先佇列,Top K等問題。

演算法導論第6章對堆的進行了詳細講解,我就不贅述了(看書是不夠的,要把思路用程式碼實現出來才是真的懂了,爭取把演算法導論上常用的資料結構和演算法都自己實現一般)。

大根堆

具體程式碼(按照演算法導論中下標從1開始):

/******* 大小堆排序 & topk問題  ***********/

//調整大根堆(大堆化),陣列從1下標開始
void adjust_maxheap(int
a[],int size,int i) { int left = i*2; //左節點 int right = i*2+1; //右節點 int max_index; //找根,左,右中最大的節點 if(left < size && a[left]>a[i]) max_index = left; else max_index = i; if(right < size && a[right] > a[max_index]) max_index = right; //如果原來的根不是最大值,則需要交換,交換後原來max值的節點變成了比較小的根
if( i != max_index ) { SWAP(a[i],a[max_index]); adjust_maxheap(a,size,max_index); } } //建立大根堆 void build_maxheap(int a[],int size) { int start = size>>1; //第一個非葉子節點 int i ; for(i = start;i>=1;i--) { adjust_maxheap(a,size,i); } } //大堆排序 void
maxheap_sort(int a[],int size) { int i; for(i = size;i>=1;i--) { build_maxheap(a,i); SWAP(a[1],a[i]); } }

測試程式碼與執行截圖:

這裡寫圖片描述

小根堆

具體程式碼(下標從0開始):

void adjust_minheap(int a[],int size,int i)
{
    int left = i*2+1;
    int right = i*2+2;

    int min_index;
    if( left < size && a[left]<a[i])
        min_index = left;
    else
        min_index = i;

    if( right < size && a[right]< a[min_index])
        min_index = right;

    if( min_index != i)
    {
        SWAP(a[i],a[min_index]);
        adjust_minheap(a,size,min_index);
    }
}

void build_minheap(int a[],int size)
{
    int start = size>>1;
    for(start;start>=0;start--)
    {
        adjust_minheap(a,size,start);
    }
}

void minheap_sort(int a[],int size)
{
    int i,j=size,last= size -1;
    for(i = 0;i<size;i++)
    {
        build_minheap(a,j--);
        SWAP(a[0],a[last]);
        last -= 1;
    }
}

測試程式碼與執行截圖:

這裡寫圖片描述

運用堆排序解決Top K問題

top k問題就是在一堆資料中選擇前K大(前K小)的資料。做法有許多,可以先把所有資料排序,然後選前k個。
然後用堆排序解決Top K問題則不用先全部排序,只需維護一個大小為K的堆即可。

實現思路:

如果要選出前K大,則將資料中的前K個元素建立成一個小根堆,從第K+1個元素開始往後依次比較,如果元素大於小根堆的堆頂,那麼就和堆頂交換,交換後重新調整為小根堆。這樣變數一遍所有資料,最後得到的大小為K的小根堆就是前K大的樹。

具體程式碼:

void topk_biggest(int a[],int size,int k)
{
    int i;

    for(i = k;i<size;i++)
    {
        build_minheap(a,k);
        if(a[i]>a[0])
            SWAP(a[i],a[0]);
    }
    printf("最大%d個數為:",k);
    for(i =0;i<k;i++)
        printf("%d ",a[i]);
}

Top k 測試程式碼&執行截圖:

這裡寫圖片描述

相關推薦

大小排序 & Top K 問題

大小堆排序 堆這種資料結構定義比較簡單,大根堆就是父節點的值大於左右子孩子節點的值(小根堆相反),而且利用陣列下標就可以很好的表現堆(不過要注意是從0 還是 1開始)。堆常用語實現優先佇列,Top K等問題。 演算法導論第6章對堆的進行了詳細講解,我就不贅述

Java 排序 Top K

1.堆   堆實際上是一棵完全二叉樹,其任何一非葉節點滿足性質:   Key[i]<=key[2i+1]&&Key[i]<=key[2i+2]或者Key[i]>=Key[2i+1]&&key[i]>=

最小解決Top K問題

問題描述: 有一組資料n個,要求取出這組資料中最大的K個值。 對於這個問題,解法有很多中。比如排序及部分排序,不過效率最高的要數最小堆,它的時間複雜度為O(nlogk)。 解題思路: 取出

最小解決 Top K 問題

Top K 問題指從一組資料中選出最大的K個數。常見的例子有:熱門搜尋前10,最常聽的20首歌等。 對於這類問題,可能我們會首先想到先對這組資料進行排序,再選取前K個數。雖然這能解決問題,但效率不高,因為我們只需要部分有序,它卻對整體進行了排序。最小堆是解決To

hadoop 中文詞頻排序 top-k 問題

    本人最近一直在hadoop領域,摸爬滾打,由於最近老是佈置了一項作業:讓統計一個檔案中出現次數最高的單詞。一看到題目我就想用hadoop來實現這個問題,由於有現成的wordcount框架,所以就在這之上進行程式的修改新增即可。     準備過程:     1、我去下

從分類,排序,top-k多個方面對推薦演算法穩定性的評價

介紹 論文名: “classification, ranking, and top-k stability of recommendation algorithms”. 本文講述比較推薦系統在三種情況下, 推薦穩定性情況. 與常規準確率比較的方式不同, 本

排序演算法整理(6)排序的應用,top K 問題

top K問題是這樣的,給定一組任意順序的數,假設有n個。如何儘快地找到它們的前K個最大的數? 首先,既然是找前K個最大的數,那麼最直觀的辦法是,n個數全部都排序,然後挑出前K個最大數。但是這樣顯然做了一些不必要的事兒。 利用堆這種資料結構,藉助前文《排序演算法整理(5)堆

Top K問題——基於排序

一、簡介 所謂的Top K問題其實就是找陣列中最大的前k個值。為此,只要我們能夠找到陣列中的第k大值,那麼Top K問題就會迎刃而解。在此宣告一下,本文寫的方法肯定不是最好的。不過最近看了幾個題,其核心都是找第k大的值。這裡,我只是總結下而已。 二、

最小的k個數1 排序實現

葉子節點 gpo 新建 void 堆排序實現 oid end 個數 時間 // 使用堆排序實現 其時間復雜度為O(nlgn) private static void buildMaxHeap(int[] input, int end) { // 從

陣列中的第K個最大元素--利用排序

題: 在未排序的陣列中找到第 k 個最大的元素。請注意,你需要找的是陣列排序後的第 k 個最大的元素,而不是第 k 個不同的元素。 例: 輸入: [3,2,1,5,6,4] 和 k = 2 輸出: 5

快速選擇排序 Quick select 解決Top K 問題

1. 思想    Quick select演算法通常用來在未排序的陣列中尋找第k小/第k大的元素。    Quick select和Quick sort類似,核心是partition。     1. 什麼是partitio

排序專題1 - leetcode215. TopK/347. Top K Frequent Elements/451. Sort Characters By Frequency

215. Kth Largest Element in an Array 題目描述 找出陣列中第k大的數。 假設k是有效的,即 1 ≤ k ≤ 陣列長度。 例子 Example 1: Input: [3,2,1,5,6,4] and

演算法題(二十六)利用排序解決找出最小的k個值問題

題目描述 輸入n個整數,找出其中最小的K個數。例如輸入4,5,1,6,2,7,3,8這8個數字,則最小的4個數字是1,2,3,4,。 分析 問題很簡單,升序排序後直接輸出前k個,不過要考慮時間複雜度的問題。可以用堆排序,構建有k個值的大頂堆,然後用堆頭部與其他值比較,堆

【資料結構】用模版實現大小、實現優先順序佇列,以及排序

    一、用模版實現大小堆    如果不用模版的話,寫大小堆,就需要分別實現兩次,但是應用模版的話問題就簡單多了,我們只需要實現兩個仿函式,Greater和Less就行了,仿函式就是用類實現一個()的過載就實現了仿函式。這個看下程式碼就能理解了。再設計引數的時候,需要把模版

快速排序Top k問題中的運用(quickSort and quickSelect in Top k)

參考http://blog.csdn.net/shuxingcq/article/details/75041795      快速排序演算法在陣列中選擇一個稱為主元(pivot)的元素,將陣列分為兩部分,使得 第一部分中的所有元素都小於或等於主元,而第二部分的所有元素都大於主

排序尋找陣列中最大的K個數

/*********************************************************************************** 堆排序(Heapsort)是指利用堆這種資料結構所設計的一種排序演算法。 堆積是一個近似完全二叉樹的結構

Top K問題——基於快速排序

一、簡介 所謂的Top K問題其實就是找陣列中最大的前k個值。為此,只要我們能夠找到陣列中的第k大值,那麼Top K問題就會迎刃而解。在此宣告一下,本文寫的方法肯定不是最好的。不過最近看了幾個題,其核心都是找第k大的值。這裡,我只是總結下而已。 二、

海量資料處理的 Top K演算法(問題) 小頂實現

問題描述:有N(N>>10000)個整數,求出其中的前K個最大的數。(稱作Top k或者Top 10)   問題分析:由於(1)輸入的大量資料;(2)只要前K個,對整個輸入資料的儲存和排序是相當的不可取的。         可以利用資料結構的最小堆(小頂堆)來

TOP-K排序演算法,從海量不重複資料中找出最大/小的K個數

如題,TOP-K排序的主要功能是找出一堆不重複資料中的最小或最大的幾個數,此處我們介紹這種型別題目的某種解法: 最大最小堆,最大堆結構裡面的每一個數不都是小於root的值麼?和我們要解決的問題很像。由此,我們可以構造一個堆,並且用它來儲存我們需要找的那幾個數。有這麼一個動態

演算法問題分類---Top-K問題與多路歸併排序

Pro1:尋找前K大數 方法1:K小根堆  後面的值若大於當前根,則替換之,並調整堆 大部分人都推薦的做法是用堆,小根堆。下面具體解釋下: 如果K = 1,那麼什麼都不需要做,直接遍歷一遍,時間複雜度O(N)。 下面討論K 比較大的情況,比如1萬。 建立一個小根堆,則根是當