寻找最大的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
原创粉丝点击