利用堆排序找出数组中前n大的元素
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <time.h>
#include <malloc.h>
#include <memory.h>
#define MAX_SIZE (1000 * 10000 + 1) #define PARENT(i) (i/2)
#define RIGHT(i) (i*2 + 1)
#define LEFT(i) (i*2)
#define EXCHANGE(a,b,t) do{t=a;a=b;b=t;}while(0) // 生成不重复的随机数序列写入文件
void gen_test_data(uint32_t cnt)
{
if( cnt >= MAX_SIZE){printf("cnt too largr\n");return;}
//uint32_t i = 0;
//char *buf = (char*)malloc(MAX_SIZE);
//for(;i < cnt;++i){buf[i] = 1;}
uint32_t n = ;
char file_name[];
snprintf(file_name,,"test_data_%d.txt",cnt);
FILE *fp = fopen(file_name,"w");
if(NULL == fp){printf("open %s error!\n",file_name);return;}
while(n < cnt)
{
int32_t nRand = rand() % cnt;
//while(buf[nRand] == 0)nRand = (nRand + 1)%cnt;
//buf[nRand] = 0;
fprintf(fp,"%d ",nRand);
++n;
}
fclose(fp);
printf("gen %s finished\n",file_name);
} // 读取文件
void read_data(int32_t arr[],const uint32_t size,uint32_t *cnt,const uint32_t data_cnt)
{
FILE *fp = NULL;
*cnt = ;
char file_name[];
if(data_cnt > size){printf("data_cnt too largr\n");return;}
snprintf(file_name,,"test_data_%d.txt",data_cnt);
fp = fopen(file_name,"r");
if(NULL == fp){printf("open %s error!\n",file_name);return;}
while(!feof(fp) && *cnt < size)
{
fscanf(fp,"%d ",&arr[*cnt]);
(*cnt)++;
}
fclose(fp);
} // 快速排序
void quick_sort(int32_t arr[],int32_t low,int32_t high)
{
if(low >= high)return;
int32_t i = low,j = high,tmp = arr[i];
while(i<j)
{
while(i<j && arr[j] <= tmp)j--;
if(i<j){arr[i] = arr[j];i++;}
while(i<j && arr[i] > tmp)i++;
if(i<j){arr[j] = arr[i];j--;}
}
arr[i] = tmp;
quick_sort(arr,low,i-);
quick_sort(arr,i+,high);
} void get_topn_quick(int32_t arr[],int32_t low,int32_t high,const int32_t topn)
{
if(low >= high || topn > high)return;
int32_t i = low,j = high,tmp = arr[i];
while(i<j)
{
while(i<j && arr[j] < tmp)j--;
if(i<j)arr[i++] = arr[j];
while(i<j && arr[i] >= tmp)i++;
if(i<j)arr[j--] = arr[i];
}
arr[i] = tmp;
int32_t n = i - low + ;
if (n == topn)return;
else if (n > topn)
get_topn_quick(arr, low, i-, topn);
else if (n < topn)
get_topn_quick(arr, i+, high, topn - n);
} void max_heapify(int32_t arr[],const uint32_t size,uint32_t i)
{
uint32_t left = LEFT(i),right = RIGHT(i),largest = ,tmp = ;
if(left<size && arr[left] > arr[i])largest = left;
else largest = i;
if(right<size && arr[right] > arr[largest])largest = right;
if(largest != i)
{
EXCHANGE(arr[i],arr[largest],tmp);
max_heapify(arr,size,largest);
}
} void min_heapify(int32_t arr[],const uint32_t size,uint32_t i)
{
uint32_t left = LEFT(i),right = RIGHT(i),largest = ,tmp = ;
if(left<size && arr[left] < arr[i])largest = left;
else largest = i;
if(right<size && arr[right] < arr[largest])largest = right;
if(largest != i)
{
EXCHANGE(arr[i],arr[largest],tmp);
min_heapify(arr,size,largest);
}
} void get_topn_heap(int32_t arr[], const int32_t arr_size, const int32_t topn)
{
int32_t i = topn / , tmp = ;
// 在[0--topn)范围内构建最小堆,即优先级队列
while (i >= )min_heapify(arr, topn, i--);
for (i = topn; i < arr_size; ++i)
{
if (arr[i] <= arr[])continue; //小于最小值,没有判断的必要
EXCHANGE(arr[], arr[i], tmp);
min_heapify(arr, topn, );
}
} void dump1(int32_t arr[],const uint32_t cnt)
{
uint32_t i = ;
for(;i < cnt;++i)
{
printf("%4d ",arr[i]);
}
printf("\n");
} void dump2(int32_t arr[],const uint32_t start,const uint32_t end)
{
uint32_t i = start;
for(;i < end;++i)
{
printf("%5d ",arr[i]);
}
printf("\n");
} int32_t main(int32_t argc, char *argv[])
{
uint32_t t = ;
int32_t *arr = (int32_t*)malloc(sizeof(int32_t)*MAX_SIZE);
int32_t *heap = (int32_t*)malloc(sizeof(int32_t)*MAX_SIZE);
int32_t *quick = (int32_t*)malloc(sizeof(int32_t)*MAX_SIZE);
uint32_t cnt = ,data_cnt = ;
for(cnt = ;cnt <= MAX_SIZE;cnt*=)
{
gen_test_data(cnt);
}
for(data_cnt = ;data_cnt <= MAX_SIZE;data_cnt*=)
{
read_data(arr, MAX_SIZE, &cnt, data_cnt);
memcpy(heap,arr,sizeof(int32_t)*MAX_SIZE);
printf("cnt=%d\n",cnt);
t = clock();
get_topn_heap(heap,cnt,cnt/);
printf("heap use time:%ld\n",clock()-t);
quick_sort(heap,,cnt/-);
//dump2(heap,0,cnt/10); memcpy(quick,arr,sizeof(int32_t)*MAX_SIZE);
t = clock();
get_topn_quick(quick,,cnt-,cnt/);
printf("quick use time:%ld\n",clock()-t);
quick_sort(quick,,cnt/-);
//dump2(quick,0,cnt/10);
if(memcmp(heap,quick,sizeof(int32_t)*(cnt/-)) == )printf("OK\n");
}
return ;
}
函数 get_topn_heap 实现了用最小堆查找数组arr中最大topn个数字,并将它们放置在数组中[0-tonp)的位置
与前面的用快速排序的方法相比,用最小堆的方法效率稍低一些,快速排序方法:http://www.cnblogs.com/tangxin-blog/p/5617736.html
对比数据:

利用堆排序找出数组中前n大的元素的更多相关文章
- 利用快速排序原理找出数组中前n大的数
#include <stdio.h> #include <stdint.h> #include <stdlib.h> #define MAX_SIZE 400001 ...
- python找出数组中第二大的数
#!usr/bin/env python #encoding:utf-8 ''''' __Author__:沂水寒城 功能:找出数组中第2大的数字 ''' def find_Second_large_ ...
- 找出数组前N大的数
这个题也是个比较有名的面试题.当然有很多变种. 题目意思基本是:从一个数据量很大的数组里找前N大的元素.不允许排序. 这个题有两个比较好的思路: 思路一:用快速排序的思想,是思想,不是要排序; 思路二 ...
- 力扣:丑数II和数组中前K大的元素
数组中的第K个元素 在未排序的数组中找到第 k 个最大的元素.请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素. 示例 1: 输入: [3,2,1,5,6,4] 和 k ...
- leecode第二天-使用异或找出数组中的非重复元素
leecode题目描述如下: 给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次.找出那个只出现了一次的元素. 思路: 最开始想到的是使用排序,排序之后就很容易找到非重复元素了. ...
- python经典面试算法题4.1:如何找出数组中唯一的重复元素
本题目摘自<Python程序员面试算法宝典>,我会每天做一道这本书上的题目,并分享出来,统一放在我博客内,收集在一个分类中. [百度面试题] 难度系数:⭐⭐⭐ 考察频率:⭐⭐⭐⭐ 题目描述 ...
- 前端算法题:找出数组中第k大的数字出现多少次
题目:给定一个一维数组,如[1,2,4,4,3,5],找出数组中第k大的数字出现多少次. 例如:第2大的数是4,出现2次,最后输出 4,2 function getNum(arr, k){ // 数组 ...
- 函数内this指向+排序+找出数组大小项+Math类
解决函数内this指向: 1,可以在函数外提前声明变量 _this/that = this 2,通过apply()和call()来修改函数内的this指向 二者区别: 用法是一样的,参数形式不一样 f ...
- 剑指offer.找出数组中重复的数字
题目: 给定一个长度为 n 的整数数组 nums,数组中所有的数字都在 0∼n−1 的范围内.数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次.请找出数组中任意一个重复的数 ...
随机推荐
- HDU3996 Gold Mine(最大权闭合子图)
#include<cstdio> #include<cstring> #include<queue> #include<algorithm> using ...
- ajax返回数据解析总结
ajax即异步 JavaScript 和 XML(Asynchronous JavaScript and XML). 简短地说,在不重载整个网页的情况下,AJAX 通过后台加载数据,并在网页上进行显示 ...
- 【BZOJ】2152: 聪聪可可(点分治)
http://www.lydsy.com/JudgeOnline/problem.php?id=2152 随便点分..... 只是我在考虑一个地方逗乐.. 当路径长度mod3=0的点数直接乘起来就好. ...
- 【BZOJ】3038: 上帝造题的七分钟2(线段树+暴力)
http://www.lydsy.com:808/JudgeOnline/problem.php?id=3038 这题我就有得吐槽了,先是线段树更新写错,然后不知哪没pushup导致te,精度问题sq ...
- HDU 4679 Terrorist’s destroy
如果不在最长路的边,那么肯定是w*最长路. 如果在最长路,那么把最长路分成两段,左边树的最长路就是左段+左边点的次短路(不包含最长路上的点的最长路) ,右边同理. 还有就是更新,经过左端点的最长路,不 ...
- COJ976 WZJ的数据结构(负二十四)
试题描述 输入一个字符串S,回答Q次问题,给你l,r,输出从Sl--Sr组成的串在S中出现了多少次. 输入 第一行为一个字符串S.第二行为一个正整数Q.接下来Q行每行为l,r. 输出 对于每个询问,输 ...
- JAVA生成RSA非对称型加密的公钥和私钥(利用JAVA API)
非对称型加密非常适合多个客户端和服务器之间的秘密通讯,客户端使用同一个公钥将明文加密,而这个公钥不能逆向的解密,密文发送到服务器后有服务器端用私钥解密,这样就做到了明文的加密传送. 非对称型加密也有它 ...
- 移动web app开发小贴士 收藏有用
1 创建主屏幕图标 (Creating a home screen icon ,for ios) 1 2 3 4 5 6 //57*57 <link rel="apple-touc ...
- WPF 一个数据库连接测试的实现
要实现的功能效果图如下:因为我们要测试数据是从输入框获得的,所以,我们的连接字符串不是写死在应用程序中的.下面我就详细介绍一下.
- mysql 动态sql语句
; SET @ss = ' INSERT INTO prod_attr SELECT ? AS prod_id,A.* FROM ( SELECT 1 AS attr_id,\'中国出版社\' AS ...