利用堆排序找出数组中前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 的范围内.数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次.请找出数组中任意一个重复的数 ...
随机推荐
- sssssssss
构造函数new A 和new A()的区别,都是A类的实例化,后者可以向构造函数传参数. a=f(),指向window a=new f()指向当前函数的实例. Return b和return b()区 ...
- Google地图接口API之地图控件集(五)
1.默认控件集 当使用一个标准的google地图,它的控件默认设置如下: (1). Zoom-显示一个滑动条来控制map的Zoom级别,如下所示:
- easyui的combobox下拉框初始化默认值以及保持该值一直显示的方法
easyui的combobox下拉框默认初始值是空,下面是实现从远程加载数据之后初始化默认值,以及让该值一直排在下拉框的最顶部的方式. 目前的需求是需要在初始化的时候添加"全部数据库&quo ...
- SignalR —— Asp.net RealTime的春天
一般的例子:http://www.asp.net/signalr/overview/signalr-20/getting-started-with-signalr-20/tutorial-gettin ...
- Insert Function before and after main function
Source code: 1: #include<stdio.h> 2: void myStartupFun (void) __attribute__ ((constructor)); 3 ...
- webapp开发经验总结
webapp开发的大趋势之下,本人收集整理了一写关于webapp开发的经验,欢迎大家补充指正. 关于link <link rel="apple-touch-startup-image& ...
- TYVJ P1012 火柴棒等式 Label:枚举
背景 NOIP2008年提高组第二题 描述 给你n根火柴棍,你可以拼出多少个形如“A+B=C”的等式?等式中的A.B.C是用火柴棍拼出的整数(若该数非零,则最高位不能是0).用火柴棍拼数字0-9的拼法 ...
- 【wikioi】1033 蚯蚓的游戏问题(费用流)
http://wikioi.com/problem/1033/ 这题也是很水的费用流啊,同之前那题一样,拆点然后建边,容量为1,费用为点权.然后建个源连第一行每个点,容量为1,费用为0,然后最后一行每 ...
- SSH配置动态数据源
用到一个项目,需要整合2个不同的数据库! 现将代码贴下,以备后用: 1.创建静态映射类,该类映射动态数据源 public class DataSourceMap { public static fin ...
- Html - SPA页面收集(有图)
场景,左图,又字段的布局 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> ...