当前位置: 首页>>算法&结构>>正文


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/article/187.html,未经允许,请勿转载。