方法一.先排序然后找出最大的K个数,这里选择快速排序,代码如下:
int partition(int *arr,int low,int high){//划分函数
int key=arr[low];
while(low<high){
while(low<high&&arr[high]>=key)high--;
arr[low]=arr[high];
while(low<high&&arr[low]<=key)low++;
arr[high]=arr[low];
}
arr[low]=key;
return low;
}
void quickSort(int *arr,int low,int high){//快排
if(low<high){
int pivot=partition(arr,low,high);
quickSort(arr,low,pivot-1);
quickSort(arr,pivot+1,high);
}
}
void getKBig(int *arr,int n,int k){
quickSort(arr,0,n-1);
if(k>n)//如果k比n大则取摸
k%=n;
for(int i=1;i<=k;i++){
printf("%d ",arr[n-i]);
}
}
方法二 用部分排序算法,找出最大的K个数。选择排序和冒泡排序都可以,这里选择选择排序,代码如下:
void selectKBig(int *arr,int n,int k){
if(k>n)//如果k比n大则取摸
k%=n;
for(int i=n-1;i>n-k-1;i--){
int index=0;//找最大的元素下标
for(int j=1;j<=i;j++){
if(arr[j]>arr[index])
index=j;
}
if(index!=i){//如果不等则交换
int temp=arr[index];
arr[index]=arr[i];
arr[i]=temp;
}
}
//输出
for(int i=1;i<=k;i++){
printf("%d ",arr[n-i]);
}
}
方法三 利用部分堆排序,建立大小为K的堆,然后遍历其后的元素与堆顶元素比较,若大则交换.代码如下:
//保持最小堆的性质,递归版本
void minHeapify(int *arr,int heapSize,int i){
int smallest=i;
int left=(i<<1)+1;
int right=left+1;
if(left<heapSize&&arr[left]<arr[smallest])
smallest=left;
if(right<heapSize&&arr[right]<arr[smallest])
smallest=right;
if(smallest!=i){
int temp=arr[smallest];
arr[smallest]=arr[i];
arr[i]=temp;
minHeapify(arr,heapSize,smallest);
}
}
//保持最小堆的性质,非递归版本(迭代版本)
void minHeapify(int *arr,int heapSize,int i){
int left,right,smallest;
while(i<heapSize){
smallest=i;
left=(i<<1)+1;
right=left+1;
if(left<heapSize&&arr[left]<arr[smallest])
smallest=left;
if(right<heapSize&&arr[right]<arr[smallest])
smallest=right;
if(smallest!=i){
int temp=arr[smallest];
arr[smallest]=arr[i];
arr[i]=temp;
i=smallest;
}else
break;
}
}
//建堆
void buildHeap(int *arr,int heapSize){
for(int i=(heapSize-2)/2;i>=0;i--)
minHeapify(arr,heapSize,i);
}
void getKBig(int *arr,int length,int k){
if(k>length)
k%=length;
buildHeap(arr,k);
int temp=0;
for(int i=k;i<length;i++)
if(arr[i]>arr[0]){
temp=arr[i];
arr[i]=arr[0];
arr[0]=temp;
minHeapify(arr,k,0);
}
for(int j=0;j<k;j++)
printf("%d ",arr[j]);
}
方法四 利用计数排序思想,但是使用范围较小,其元素必须是整数且不是很大,代码如下:
int getKBig(int *arr,int length,int k){
//如果大于长度则取摸
if(k>length)
k%=length;
//找最大值
int max=arr[0],i;
for(i=1;i<length;i++){
if(arr[i]>max)
max=arr[i];
}
int *count=new int[max+1];
//初始化为零
for(i=0;i<=max;i++)
count[i]=0;
//统计每个元素出现的次数
for(i=0;i<length;i++)
count[arr[i]]++;
//统计第K大的数
int pc=0;
for(i=max;i>=0;i--){
pc+=count[i];
if(pc>=k)
break;
}
//输出
for(int j=0;j<length;j++)
if(arr[j]>=i)
printf("%d ",arr[j]);
return i;
}
方法五 寻找第K大的数,然后再扫描一趟原数组
//分割
int randomizedPartition(int *A,int low,int high){
//set the key value
int key=A[low];
while(low<high){
while(low<high&&A[high]>=key)high--;
A[low]=A[high];
while(low<high&&A[low]<=key)low++;
A[high]=A[low];
}
A[low]=key;
return low;
}
//选择第K大的数
int randomizedSelect(int *A,int s,int t,int i){
if(s==t)
return A[s];
int p=randomizedPartition(A,s,t);
int k=t-p+1;
if(k==i)
return A[p];
else if(k>i)
return randomizedSelect(A,p+1,t,i);
else
return randomizedSelect(A,s,p-1,i-k);
}
//最大的K个数
void getKBig(int *arr,int length,int k){
if(k>length)
k%=length;
int key=randomizedSelect(arr,0,length-1,k);
//输出
for(int j=0;j<length;j++)
if(arr[j]>=key)
printf("%d ",arr[j]);
}