當前位置: 首頁>>算法&結構>>正文


top-k算法的二分實現(修正版)(C++實現)

摘要:本文簡要介紹了top-k(求一個序列中前K個最大或最小的元素)算法的二分實現方法,並給出了C++源

代碼

關鍵字:top-k,二分,快排序

網上介紹top-k算法的博文貌似不多,有一個搜索引擎中排名靠前的top-k算法介紹中給出了源碼,

我試了試,發現有點小BUG,就自己整理了一下,先說說實現原理,後麵給出源碼。

top-k的實現方法比較常見的有堆和二分法,這裏隻介紹二分實現方法,具體思路如下:

以求長度為N的整數數組中前K個最大數為例,類似於快排序,本方法遞歸地把數組分為兩部分

(設劃分點索引為M),將大的數放到左邊部分,將小的數放到右邊部分。如果M大於K

對數組0~(M-1)部分執行top-k算法;如果M小於等於K,計上一次劃分點索引為LAST, 對數組0~LAST

進行快排序。運行結束後,數組的0~(K-1)即為最大的K個整數!算法的時間複雜度為O(N*log2K),適合

數據可以全部裝入內存的情形!

源碼如下(VC++ 6.0編譯測試通過):


/*
 * 二分實現top-k算法
 * 取長度為N的整數數組中前K個最大的數
 */

#include <iostream>
#include <ctime>
using namespace std;

#define MAX_NUM 1000

#define N 200

#define K 20

/* global data */

int array[N];

/* funcitons declaration*/
void init_array(int n);
void print_result(int n);
void quicksort(int low, int high);
void topk(int low, int high, int k);

/* main */

int main(int argc, char* *argv)
{
        cout<<"init array,size:"<<N<<"......"<<endl;
        init_array(N);
        print_result(N);
        cout<<"generate top-"<<K<<"......"<<endl;
        topk(0, N - 1, K);
        cout<<"result....."<<endl;
        print_result(K);
        system("pause");
        return 0;
}

/* function definition */

void init_array(int n)
{
        for(int i = 0; i < n; ++i)
        {
                array[i] = rand() % MAX_NUM;
        }
}

void print_result(int n)
{
        for(int i = 0; i < n; ++i)
        {
                cout<<array[i]<<" ";
        }
        cout<<endl;
}
       
void mswap(int i, int j)
{
        int temp = array[i];
        array[i] = array[j];
        array[j] = temp;
}
void quicksort(int low, int high)
{
        if(low >= high) return;
        mswap(low, rand() % (high - low + 1) + low);
        int m = low;
        for(int i = low + 1; i <= high; ++i)
        {
                if(array[i] > array[low])
                {
                        mswap(++m, i);
                }
        }
        mswap(m, low);
        quicksort(low, m - 1);
        quicksort(m + 1, high);
}

void topk(int low, int high, int k)
{
        static int last = high;
        if(low >= high) return;
        mswap(low, rand() % (high - low + 1) + low);
        int m = low;
        for(int i = low + 1; i <= high; ++i)
        {
                if(array[i] > array[low])
                {
                        mswap(++m, i);
                }
        }
        mswap(m, low);
        if(k < m)
        {
                last = m;
                topk(low, m - 1, k);
        }
        else
        {
                quicksort(low, last);
        }
}
本文由《純淨天空》出品。文章地址: https://vimsky.com/zh-tw/article/187.html,未經允許,請勿轉載。