在Jacky一篇关于Oracle排序算法的文章中,讨论了下Oracle的Short sort算法。文章中对此算法有详细描述,这里不赘述,大致就是通过Heap来实现。
虽然Heap在处理优先队列类型的问题上很有优势,但是我一致觉得它不太适合做排序,调堆的代价其实是比较高的,每加入一个元素删除一个元素都要调堆。
对于TopK的问题,我还是觉得二分法实现比较好。首先按快排的算法把数据分成两堆,左大右小,再判断左边的大堆是不是数量小于了K,小于了了就使用上次的右边界进入排序流程,不到则继续二分。
#include <iostream>
#include <cstdlib>
#include <time.h>
#include <math.h>
#define MAXN 10000
#define LIMIT 500
int a[MAXN];
int last;
int count_sw, count_cmp;
//初始化测试数据
void init () {
srand(time(0));
//参与查询的数据
for(int i=0; i<MAXN; ++i) {
a[i] = rand()%MAXN;
}
return ;
}
void swap(int &x, int &y) {
int t ;
t = x;
x = y;
y = t;
return ;
}
void qsort(int arr[], int start, int end) {
if(start < end) {
int mid = arr[rand()%(end-start) + start];
int i = start - 1;
int j = end + 1;
while (true) {
while (arr[++i] > mid) count_cmp++;
while (arr[--j] < mid) count_cmp++;
if(i>=j) break;
swap(arr[i], arr[j]);
count_sw++;
}
qsort (arr, start, i-1);
qsort (arr, j+1, end);
}
return ;
}
void topK(int arr[], int start, int end, int k) {
if(start < end) {
int mid = arr[rand()%(end-start) + start];
int i = start - 1;
int j = end + 1;
while (true) {
while (arr[++i] > mid) count_cmp++;
while (arr[--j] < mid) count_cmp++;
if(i>=j) break;
swap(arr[i], arr[j]);
count_sw++;
}
if(i-start > k) {
last = i-1;
topK (arr, start, i-1, k);
} else{
qsort(arr, start, last);
}
}
return ;
}
int main() {
init();
count_sw = 0;
count_cmp = 0;
topK(c, 0, MAXN-1,10);
cout << "Result:" << MAXN << endl;
for(int i=0; i<10; ++i) {
cout << c[i] << endl;
}
cout << "Swaps:" << count_sw << endl;
cout << "Campare:" << count_cmp << endl;
return 0;
}
转自网址: http://www.penglixun.com/tech/program/dichotomy_topk_cpp.html
分享到:
相关推荐
本篇文章主要探讨的是利用二分法实现Top K算法。 **一、二分法实现Top K算法** 1. **基本思想** 二分法实现的Top K算法的核心是通过不断地将数据集划分为两部分,每次保证一部分的大小不超过K,从而逐步缩小搜索...
Top100常见题: 关于Python的详细题解记录在,有兴趣的小伙伴可以关注下。 刷题记录: 题目 难度 时间复杂度 类型 完成度 方法 1.两数之和 Easy $O(n)$ 数组、哈希表 Done key为数,value为index保存字典,判断差...
### CH0709:查找二分法 **题目描述**: 本程序采用二分查找算法在一个已排序的数组中查找指定的元素。 **关键知识点**: 1. **数组初始化**:预先定义并初始化一个数组。 ```c inta[15]={1,4,9,13,21,34,55,89,...
Top100常见题: 关于Python的详细题解记录在,有兴趣的小伙伴可以关注下。 刷题记录: 题目 难度 时间复杂度 类型 完成度 方法 1.两数之和 Easy $O(n)$ 数组、哈希表 Done key为数,value为index保存字典,判断差...
6. 只有顺序存储的有序线性表可以使用二分法进行查找,因为二分法依赖于数据的有序性。 7. 在很多编程语言中,`local`或类似的命令用于在函数或代码块内部定义局部变量。 8. 在同一学校中,一个系可以有多名教师,...
这是根据满二叉树的性质计算得出的,深度为n的满二叉树节点数为2^n - 1。 11. 软件测试中,功能测试属于黑盒测试,关注的是软件的功能表现;单元测试属于白盒测试,关注的是代码内部逻辑。 12. 错误描述:软件的...
4. 二分法查找函数,用于判断顺序数组A中是否存在数字n。 5. 编码函数,将每7个字节加1个校验字节,使得8字节和为0。具体实现需考虑边界条件和校验字节的计算。 三、数据库题 1. ADOQuery.ExecSQL执行SQL语句(通常...