寻找最大的K个数
来源:互联网 发布:geohot编程能力 编辑:程序博客网 时间:2024/05/21 07:53
问题:查找大量无序元素中最大的K个数。
解法1:利用快速排序的切分函数查找最大的K个数。
代码1:
void swap(int *a,int *b){int t = *a;*a = *b;*b = t;}int partition(int *a,int left,int right){int pivot = a[left];int i = left;int j = right;while(i < j){while (i < j && a[j] >= pivot) --j;if (i < j) swap(&a[i++],&a[j]);while (i < j && a[i] <= pivot) ++i;if (i < j)swap(&a[i],&a[j--]);}return j;}int findMaxK(int *a,int left,int right,int K){/*max K elements at the end of the array*/assert(K <= (right - left + 1));int p = partition(a,left,right);if ( K == right - p + 1)return p;else {if (K < right - p + 1)return findMaxK(a,p+1,right,K);elsereturn findMaxK(a,left,p-1,K - (right - p + 1));} }
解法2:将数组的前K个数构造为最小堆,从第K+1个元素开始,与第一个元素比较,若此元素比第1个元素大那么交换这两个元素,然后进行最小堆调整。
代码2:
void heapify(int *a,int root,int end){/* end : the max subscript */int child = root * 2 + 1;int pivot = a[root];while(child <= end){if (child < end && a[child] > a[child+1])child++;if (pivot < a[child])break;else {a[(child-1)>>1] = a[child];child = child * 2 + 1;}}a[(child-1)>>1] = pivot;}void minHeapify(int *a,int n){/* n : the length of a[] */for (int i = (n - 2)/2; i >= 0; i--){heapify(a,i,n-1);}}void findMaxK(int*a,int n,int K){assert(K <= n);minHeapify(a,K);for (int i = K;i < n; i++){if (a[i] > a[0]){swap(&a[i],&a[0]);minHeapify(a,K);}}}
测试程序:
#include <stdio.h>#include <assert.h>#include <time.h>#include <stdlib.h>void swap(int *a,int *b){int t = *a;*a = *b;*b = t;}int partition(int *a,int left,int right){int pivot = a[left];int i = left;int j = right;while(i < j){while (i < j && a[j] >= pivot) --j;if (i < j) swap(&a[i++],&a[j]);while (i < j && a[i] <= pivot) ++i;if (i < j)swap(&a[i],&a[j--]);}return j;}int findMaxK(int *a,int left,int right,int K){/*max K elements at the end of the array*/assert(K <= (right - left + 1));int p = partition(a,left,right);if ( K == right - p + 1)return p;else {if (K < right - p + 1)return findMaxK(a,p+1,right,K);elsereturn findMaxK(a,left,p-1,K - (right - p + 1));} }/*---------------------------------------------------------------------*/void heapify(int *a,int root,int end){/* end : the max subscript */int child = root * 2 + 1;int pivot = a[root];while(child <= end){if (child < end && a[child] > a[child+1])child++;if (pivot < a[child])break;else {a[(child-1)>>1] = a[child];child = child * 2 + 1;}}a[(child-1)>>1] = pivot;}void minHeapify(int *a,int n){/* n : the length of a[] */for (int i = (n - 2)/2; i >= 0; i--){heapify(a,i,n-1);}}void findMaxK(int*a,int n,int K){assert(K <= n);minHeapify(a,K);for (int i = K;i < n; i++){if (a[i] > a[0]){swap(&a[i],&a[0]);minHeapify(a,K);}}}/*---------------------------------------------------------------------*/void show(int *a,int n){for (int i = 0; i < n; i++)printf("%3d",a[i]);printf("\n");}int main(){srand(time(NULL));int a[10];int N = 10;for (int i = 0; i < N; i++)a[i] = rand() % 101;show(a,10);findMaxK(a,0,9,4);show(a,10);findMaxK(a,10,4);show(a,10);}
REF:
1,编程之美 2.5
0 0
- 寻找最大的K个数
- 寻找最大的K个数
- 寻找最大的k个数
- 寻找最大的K个数
- 寻找最大的K个数
- 寻找最大的K个数
- 寻找最大的K个数
- 寻找最大的K个数
- 寻找最大的K个数
- 寻找最大的K个数
- 寻找最大的K个数
- 寻找最大的K个数
- 寻找最大的k个数
- 寻找最大的K个数
- 寻找最大的K个数
- 寻找最大的K个数
- 寻找最大的K个数
- 寻找最大的k个数
- 为虚拟机硬盘扩容(Oracle VM VirtualBox)的方法啊
- 【翻译自mos文章】SGA_TARGET与SHMMAX的关系
- hihoCoder- Trie树
- 白书上的AC自动机模板
- hdu 1284 钱币兑换问题
- 寻找最大的K个数
- HDU 1010 Tempter of the Bone 深搜剪枝
- poj 2229 Sumsets(递推&整数划分变形)
- 并归排序
- 数据线为什么容易坏
- ios--window的基本概念和用法
- 配置Openstack 中最复杂灵活的网络模型:每个租户都拥有自己的路由及内部网络
- 网络应用开发基础一
- hdu 1012 u Calculate e