N个数求最大的k个数

计划之中,每周日,做点算法题。希望能有所进步。

看了一个在N个数中求k个数,我的第一感觉应该是用堆来解决。确实堆是可行的,这里给出一个快排思想的求法,时间复杂度为O(N*log2^k)。

然后再弄个堆维护的例子。

以前搞ACM的时候,有点浮躁,但愿能够在静下来的时候多多考虑算法。

#include <stdlib.h>
#include <stdio.h>
void swap(int *a, int *b) {
	int temp = *a;
	*a = *b;
	*b = temp;
}
void  find_k(int a[], int left, int right, int k) {
	if ( k <= 0)
		return;
	int s = left, i, j;
	if(right - left+1 <= k) { 			/*ok*/
		for(j = left ; j <= right ;j++)
			printf("%d  ",a[j]);
		return;
	}

	for( i = left ; i < right ;i++ ) {		
		if(a[i] > a[right]) {
			swap(&a[s++], &a[i]);
		}
	}
	swap(&a[s], &a[right]);
	if(s - left   >= k) {
		find_k(a, left, s - 1, k);
	}
	else {
		find_k(a, left, s-1, s-left);
		find_k(a,s, right, k -(s-left));
	}
}
int main ( ) {  
    int         a[100], n, k, i;  
    scanf("%d %d", &n, &k);  
    for( i = 0 ;i < n ;i++) {  
        scanf("%d", &a[i]);  
    }  
  find_k(a, 0 ,n-1, k);
  printf("\n");
    exit(0);  
}  

堆维护

#include <stdlib.h>
#include <stdio.h>
#define MAXSIZE		100
int		heap[MAXSIZE];
int		heapsize;
int		valmax;
/*
*首先将需要插入的数据,放在数组尾部。
* 那么这个元素破坏了堆的规则。需要将它上浮
*直到满足规则
*/

int ins_heap(int no) { 
	heapsize ++;
	int 	pos = heapsize;
	int	parent = pos/2;
	int	target = heap[heapsize] = no;
	while(parent != 0) {
		if(heap[parent] <= target) {
			break;
		}
		else {
			heap[pos] = heap[parent];
			heap[parent] = target;
			pos = parent;
			parent = pos /2;
		}
	}
	return heapsize;
}
/*
*删除堆顶元素。然后将数组尾部元素放在堆顶,破坏堆
*结构。将此元素与他的左右子节点比较,取最小的交换
*一直下沉直到满足堆的规则
*/
int  del_heap( ) {
	int 	pos = 1;
	int 	ret;
	int 	left ;
	int 	right ;
	int   mixval, temp, ptr;
	ret = heap[pos];
	heap[pos] =  heap[heapsize];
	heapsize -- ;
	while(pos*2 <= heapsize) {					/**/
		left = pos * 2 ;
		right = pos *2 +1;
		mixval = (heap[left]<heap[right]) ? heap[left]: heap[right];
		if(mixval == heap[left])
			ptr = left;
		else if(mixval == heap[right])
			ptr = right;
		if(heap[pos] < mixval)
			break;
		else {
			temp = heap[pos];
			heap[pos] = heap[ptr];
			heap[ptr] = temp;
			pos = ptr;
		}
	}
	return ret;
}
void init_heap(int a[], int n) {
		
}

int main ( ) {  
	int         a[100], n, k, i;  
	heapsize = 0;
    	scanf("%d %d", &n, &k);  
    	for( i = 0 ;i < n ;i++) {  
        scanf("%d", &a[i]);  
		if(i < k) {
			ins_heap(a[i]);
			if(a[i] < valmax) {
				valmax = a[i];
			}
			continue;
		}
		if(a[i] > valmax) {
			del_heap();
			ins_heap(a[i]);
			valmax = heap[1];
		}
    	}  
	int t= heapsize;
	for( i = 1 ;i <= t; i++) {	
		printf("%d ", heap[i]);
	}
	printf("\n");
       exit(0);  
}  

/*
9 5
24 10 90 77 16 25 33 89 67

*/

test1:

9 5
24 10 90 77 16 25 33 89 67
33 67 90 89 77

test 2:

9 3
24 10 90 77 16 25 33 89 67
77 90 89 

点赞