在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
分享到:
相关推荐
SQL二分法。 双TOP二分 当前记录排序
在这个特定的例子中,我们关注的是使用C语言来解决一元N次方程的求根问题,特别是通过二分法。C语言是一种底层、高效且广泛使用的编程语言,非常适合这样的数学计算任务。 一元N次方程是指只含有一个变量的多项式...
printf("方程的根大约是:%.4f\n", root); return 0; } ``` 在这个例子中,我们首先定义了一个函数f(x) = x^2 - 4,然后使用二分法递归函数`binary_search`来求解它的根。主函数`main`中设置了初始区间[-5, 5]和...
二分法流程图1 二分法是一种常用的数值计算方法,用于寻找单变量函数的零点。它的基本思想是通过不断地将搜索范围缩小,来逼近函数的零点。下面我们将通过流程图来详细地介绍二分法的工作过程。 首先,我们需要...
二分法的优点在于其效率高,时间复杂度为O(log n),远优于线性搜索的O(n)。但它的前提是数据必须已经排序,对于无序数据,二分法并不适用。此外,二分法在处理大型数据集时特别有效,因为每次操作都能显著减少搜索...
二分法(dichotomie) 即一分为二的方法.... 逐次二分法就是造出如下的区间序列([an,bn]):a0=a,b0=b,且对任一自然数n,[an+1,bn+1]或者等于[an,cn],或者等于[cn,bn],其中cn表示[an,bn]的中点.
二分法的使用 二分法是一种常用的数值计算方法,用于找到函数的零点或极值。在计算机科学中,二分法是解决直际问题的重要工具。下面我们将详细介绍二分法的使用和实践。 二分法的定义 二分法是一种数值计算方法,...
标题中的“温度转换二分法”是指在处理温度测量时,采用二分法来查找温度对应的电压或电阻值。二分法,又称折半查找法,是一种高效的算法,常用于有序数据集合中寻找特定元素。在温度测量领域,如果我们有一个预设的...
在编程领域,二分法(也称为二分查找)是一种高效的数据搜索算法,尤其适用于已排序的数组或列表。在VC++6.0这个经典的微软Visual C++开发环境中,我们可以利用C++语言来实现二分法。对于初学者来说,理解和掌握...
printf("Root is approximately: %.4f\n", root); return 0; } ``` 在这个例子中,我们求解了方程x^2 - 4 = 0,并设定误差阈值为0.0001。程序首先初始化区间[-5, 5],然后在每次迭代中,通过比较中间点的函数值与...
标题“N2121_二分法_bited6z_”可能是指一个关于二分法的实例或者教学资源,其中“N2121”可能是某种编号或课程代码,“bited6z”可能是作者的名字或者文件的编码方式。这个压缩包中的唯一文件“N2121.m”很可能是一...
这个过程每次都将搜索区域减半,因此二分法的效率很高,其时间复杂度为O(log n),n为初始区间的大小。然而,二分法依赖于方程的连续性,对于某些非连续函数可能不适用。 在实际应用中,二分法常用于数值计算,尤其...
根据给定的文件信息,我们可以总结出以下关于“二分法排序算法C语言实现”的相关知识点: ### 1. 二分法搜索算法原理 二分法搜索算法,也称为折半查找算法,是一种在有序数组中查找特定元素的搜索算法。其基本思想...
根据给定的信息,我们可以详细解析二分法与牛顿法这两种数值分析方法,并结合具体的MATLAB函数实现进行深入探讨。 ### 二分法 #### 定义与原理 二分法(Bisection Method)是一种求解非线性方程根的数值方法,适用...
在含有n个元素的有序数列中,传统二分法查找在平均和最坏情况下的时间复杂度均为O(log n),远快于线性查找的O(n)。 尽管二分法查找已经相当高效,但是在实际应用中,有序数列的特性有时可以为我们提供额外的线索。...
二分法查找的时间复杂度为O(log n),是当前最快的查找算法之一。 在上面的代码中,BinSearch函数是二分法查找的实现,函数的参数为数组R、数组长度n和要查找的元素k。函数首先计算中间索引mid,然后比较中间元素与...
利用java二分法来计算最靠近值,通过二分法来遍历数据,得到想要最近值
二分法查找,又称折半查找,是一种在有序数组中搜索特定元素的高效算法。它通过不断缩小搜索范围,将查找复杂度降低到对数级别,显著提高了查找效率。在这个资源包中,我们重点关注的是使用C语言实现的二分法查找...
简单的做了一个二分法的算法,小于某个特定值后停止运行。
二分法