区间 top k

来源:互联网 发布:edius4.7软件下载 编辑:程序博客网 时间:2024/05/24 05:57

按编程之美上解法二的所述,类似快速排序的划分方法,N个数存储在数组S中,再从数组中随机选取一个数X,把数组划分为Sa和Sb俩部分,Sa<=X<=Sb,如果要查找的k个元素小于Sa的元素个数,则返回Sa中较小的k个元素,否则返回Sa中所有的元素+Sb中较小的k-|Sa|个元素。不断递归下去,把问题分解成更小的问题,平均时间复杂度为O(N)


// Copyright 2012 Jike Inc. All Rights Reserved.// Author: jichenghui@jike.com(Chenghui Ji)// Date  : 2012-08-24 16:35:51// Brief : #include <iostream>using namespace std;int partition(int* data, int left, int right) {  if (left > right) {    return -1;  } else {    int polit = data[left];    while(left < right) {      while(right > left && data[right] >= polit)         right--;      data[left] = data[right];      while (left < right && data[left] <= polit)        left++;      data[right] = data[left];    }    data[left] = polit;  }  return left;}void topk_qsort(int* data, int left, int right, int k) {  if (left >= right || k > right - left + 1) {    return;  }  int polit =  partition(data, left, right);  if (polit < left || polit >= right) return;  int left_len = polit - left + 1;  if (left_len == k) return;  else if (left_len > k) {    topk_qsort(data, left, polit-1, k);  } else {    topk_qsort(data, polit + 1, right, k - left_len);  }}int main() {  int data[] = {13,2,3,5,67,8,9,10,17,6};  int len = sizeof(data)/sizeof(data[0]);  cout << "orignal data:" << endl;  for (int i = 0; i < len; ++i) {    cout << data[i] << " ";  }  cout << endl;  int k = 3;  cout << "top" << k << "data:" << endl;  topk_qsort(data, 0, len-1, k);  for (int i = 0; i < len; ++i) {    cout << data[i] << " ";  }  cout << endl;  return 0;}