首页 > 代码库 > 查找最小的k个元素

查找最小的k个元素

题目: 输入n个整数,输出其中最小的k个数

例如: 1 2 3 4 5 6 7 8 这8个数字,则最小的4个数字为1,2,3,4,

第一种:直接对其先排序,再取头几个数 这样最快是nlogn(快排或者堆排)

#include <iostream>
using namespace std; 
void partsort(int a[], int l, int r); 
void QuickSort(int a[], int n)
{	
	partsort(a,0,n-1);
}
void partsort(int a[], int l, int r)
{
	int x = a[l];
	int i = l, j = r;
	if( i < j )
	{	while( i < j)
		{	
			while( i < j && a[j] > x)j--;
			if( i < j )
			{
				a[i++] = a[j];
			}	
			while( i < j && a[i] < x)i++;
			if( i < j )
			{
				a[j--] = a[i];		
			}
		}
		a[i] = x;
		partsort(a,l,i-1);
		partsort(a,i+1,r);
	}
}
int main()
{
	int a[] = {9,8,7,3,4,1,6};
	QuickSort(a,7);
	for(int i = 0; i < 3; i++)
	{
		cout << a[i] << endl;
	}
	return 0;
}

这里用快排,为nlogn


第二种: 用insert-sort   时间复杂度为(kn),即取前几个数就对找前几个数

void insertsort(int a[], int n, int k)   //k为前n个数
{
	for(int i = 0; i < k; i++)   
	{
	  for(int j = i+1; j < n; j++)  
		  if(a[j] < a[i])
		  	swap(a[j],a[i]);		
	}
		
}
第三种:
是最快的了  n+klog(n)  创建最小堆堆用o(n)的时间复杂度  取k-1次最顶上数

#include <iostream>
using namespace std;
 void MaxHeapDown(int a[], int i, int n)
{
	int j, temp;
	
	temp = a[i];
	j = 2*i + 1;
	while(j < n)
	{
		if ( j + 1 < n && a[j + 1] > a[j])j++;	//在左右子节点找到最大的
		if(a[j] <= temp)						//左右子树的值都小temp,即这个位置合适 
			break;
		a[i] = a[j];							//否则将子节点赋给父节点,插入的位置向下移动 
		i = j;									//向下移动 
		j = 2*j + 1; 							//向下移动 
	}
	a[i] = temp;								
}
void MakeMaxHeap(int a[], int n)
{
	for(int i = n/2 -1; i >= 0; i--)	//从最后一个父节点开始向前调整 
	{
		MaxHeapDown(a,i,n);
	}
}
void MaxHeapSort(int a[], int n)
{
	MakeMaxHeap(a,n); 	//建立堆 
	for(int i = n - 1; i >= 1; i--)
	{
		swap(a[i],a[0]);
		MaxHeapDown(a,0,i);			//这里是有i个元素,a[i]已经取不到了	
	}
	
}
int MinHeapDown(int a[], int i, int n)
{
	int j = i*2+1;
	int temp = a[i];
	while( j < n )
	{
		if( j + 1 < n && a[j + 1] < a[j])j++;
		 if( a[j] > temp )break;
		 
		 a[i] = a[j];
		 i = j;
		 j = 2*j+1;
	}
	a[i] = temp;
}
int MakeMinHeap(int a[], int n)
{
	for(int i = n/2-1; i >=0; i--)
	{
		MinHeapDown(a,i,n);
	}
}
void MinHeapSort(int a[], int n)
{
	MakeMinHeap(a,n);
	for(int i = n-1; i >= 0; i--)
	{
		swap(a[i],a[0]);
		MinHeapDown(a,0,i);
	}
}

/*本题的解决方法*/ 
void FindKMinNum(int a[],int n,int k)
{
	MakeMinHeap(a,n);
	for(int i = n-1; i >= n-k; i--)
	{
		cout << a[0] << endl;
		swap(a[i],a[0]);
		MinHeapDown(a,0,i);
	}
	
}
int main()
{
	int a[] = {9,7,5,3,4,7,3,1};
//		MaxHeapSort(a,8);
//		MinHeapSort(a,8);
		FindKMinNum(a,8,4);		
		//for(int i = 0; i < 8; i++)
		//	cout << a[i] << endl;
		return 0;
} 
从头到尾再复习了一遍堆排序。

查找最小的k个元素