不排序,两种方法找到无序数组的最大K个数

   虽然不排序,这两种方法都源于经典的排序算法的扩展

  方式一,快速排序的扩展

  1. /************************************************************************/  
  2. /*找到无序数组中最大的k个数                     */  
  3. /************************************************************************/  
  4. #include <iostream>   
  5. #include <stdlib.h>   
  6. #include <time.h>   
  7. using namespace std;  
  8.   
  9. //找到一个位置,使得左边的数比它大,右边的数比他小   
  10. int Partion(int arr[],int start,int end)  
  11. {  
  12.     int i=start,j=end;  
  13.     int temp=arr[start];  
  14.   
  15.     while(i<j)  
  16.     {  
  17.         while( (i<j) &&(arr[j] <= temp) ) j--;  
  18.         arr[i]=arr[j];  
  19.         while((i<j) && (arr[i]>=temp) ) i++;  
  20.         arr[j]=arr[i];  
  21.     }  
  22.     arr[i]=temp;  
  23.   
  24.     return i;  
  25. }  
  26.   
  27. void FindK(int arr[],int start,int end,int k)  
  28. {  
  29.       
  30.     if(start<end)  
  31.     {  
  32.         int p=Partion(arr,start,end);  
  33.         if(p>k)   
  34.         {  
  35.             FindK(arr,start,p-1,k);  
  36.         }  
  37.         else  
  38.             if(p<k)  
  39.             {  
  40.                 FindK(arr,p+1,end,k-p);  
  41.             }  
  42.     }  
  43. }  
  44.   
  45.   
  46. int *Create(int n)  
  47. {  
  48.     int *p=new int[n];  
  49.     int i=0;  
  50.   
  51.     srand(time(NULL));  
  52.   
  53.     for(;i<n;i++)  
  54.     {  
  55.         p[i]= rand()%10;  
  56.         cout<<p[i]<<" ";  
  57.     }  
  58.     cout<<endl;  
  59.     return p;  
  60. }  
  61.   
  62. void main()  
  63. {  
  64.     int *arr=NULL;  
  65.     int k=0,n=0;  
  66.   
  67.     cin>>n;  
  68.     arr=Create(n);  
  69.   
  70.     cin>>k;  
  71.     FindK(arr,0,n-1,k);  
  72.   
  73.     for(int i=0;i<k;i++)  
  74.         cout<<arr[i]<<"  ";  
  75.     cout<<endl;  
  76.   
  77.     delete arr;  
  78. }  
/************************************************************************/
/*找到无序数组中最大的k个数						*/
/************************************************************************/
#include <iostream>
#include <stdlib.h>
#include <time.h>
using namespace std;

//找到一个位置,使得左边的数比它大,右边的数比他小
int Partion(int arr[],int start,int end)
{
	int i=start,j=end;
	int temp=arr[start];

	while(i<j)
	{
		while( (i<j) &&(arr[j] <= temp) ) j--;
		arr[i]=arr[j];
		while((i<j) && (arr[i]>=temp) ) i++;
		arr[j]=arr[i];
	}
	arr[i]=temp;

	return i;
}

void FindK(int arr[],int start,int end,int k)
{
	
	if(start<end)
	{
		int p=Partion(arr,start,end);
		if(p>k) 
		{
			FindK(arr,start,p-1,k);
		}
		else
			if(p<k)
			{
				FindK(arr,p+1,end,k-p);
			}
	}
}


int *Create(int n)
{
	int *p=new int[n];
	int i=0;

	srand(time(NULL));

	for(;i<n;i++)
	{
		p[i]= rand()%10;
		cout<<p[i]<<" ";
	}
	cout<<endl;
	return p;
}

void main()
{
	int *arr=NULL;
	int k=0,n=0;

	cin>>n;
	arr=Create(n);

	cin>>k;
	FindK(arr,0,n-1,k);

	for(int i=0;i<k;i++)
		cout<<arr[i]<<"  ";
	cout<<endl;

	delete arr;
}


方式二,堆排序的扩展

  1. /************************************************************************/  
  2. /*用建堆的方法实现找到最大的K个数                                       */  
  3. /************************************************************************/  
  4.   
  5. #include <iostream>   
  6. #include <stdlib.h>   
  7. #include <time.h>   
  8. using namespace std;  
  9.   
  10.   
  11. //建立小顶堆   
  12. void HeapAjust(int arr[],int start,int end)  
  13. {  
  14.     int temp=arr[start];  
  15.     for(int i=start*2;i<=end;i*=2)  
  16.     {  
  17.         if(i<end && arr[i+1]<arr[i]) i++;  
  18.         if(temp<arr[i]) break;  
  19.         arr[start]=arr[i];  
  20.         start=i;  
  21.     }  
  22.   
  23.     arr[start]=temp;  
  24. }  
  25.   
  26. void Findk(int arr[],int n,int k)  
  27. {  
  28.     int i=0;  
  29.     int temp;  
  30.   
  31.     //建立k个节点的小顶堆   
  32.     for(i=k/2;i>0;i--)  
  33.         HeapAjust(arr,i,k);  
  34.   
  35.     for(i=k+1;i<=n;i++)  
  36.     {  
  37.         if(arr[i]>arr[1])//k中和最小的数比较   
  38.         {  
  39.             temp=arr[1];  
  40.             arr[1]=arr[i];  
  41.             arr[i]=temp;  
  42.   
  43.             HeapAjust(arr,1,k);  
  44.         }  
  45.     }  
  46. }  
  47.   
  48. int *Create(int n)  
  49. {  
  50.     int *p=new int[n+1];  
  51.     int i=0;  
  52.   
  53.     srand(time(NULL));  
  54.   
  55.     p[0]=0;  
  56.     for(i=1;i<=n;i++)  
  57.     {  
  58.         p[i]= rand()%10;  
  59.         cout<<p[i]<<" ";  
  60.     }  
  61.     cout<<endl;  
  62.     return p;  
  63. }  
  64.   
  65. void main()  
  66. {  
  67.     int *arr=NULL;  
  68.     int k=0,n=0;  
  69.   
  70.     cin>>n;  
  71.     arr=Create(n);  
  72.   
  73.     cin>>k;  
  74.     Findk(arr,n-1,k);  
  75.   
  76.       
  77.     for(int i=1;i<=k;i++)  
  78.         cout<<arr[i]<<"  ";  
  79.     cout<<endl;  
  80.   
  81.     delete arr;  
  82. }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值