编程之美--寻找最大的K个数

来源:互联网 发布:php curl get 参数 编辑:程序博客网 时间:2024/05/11 02:29

  方法一.先排序然后找出最大的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;}elsebreak;}}//建堆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 valueint 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);elsereturn 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]);}

0 0
原创粉丝点击