①快排法
②小顶堆法
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<time.h>
#define N 20
#define SWAP(a,b) {int t=a;a=b;b=t;}
//数组下标从0开始
//left是堆顶的下标,编号是left+1
//左孩子编号2*left+2,下标是2*left+1
//右孩子编号2*left+3,下标是2*left+2
void adjustMinHeap(int *p,int left,int right)//调整为小顶堆
{//自上而下调整
int father=left;
int son=2*father+1;//son指向更小的孩子
while(son<=right)
{
if(son+1<=right&&p[son]>p[son+1])//son+1<=right保证了没有右孩子就不会比较两个孩子
{
son=son+1;//右孩子小就指向右孩子
}
if(p[father]>p[son])
{
SWAP(p[father],p[son]);
father=son;
son=2*father+1;
}
else
{
break;
}
}
}
void buildMinHeap(int *p,int left,int right)//建立小顶堆
{
int lastFather=(right-1)/2;//最后一个分支结点
for(int i=lastFather;i>=left;i--)
{//自下而上建堆
adjustMinHeap(p,i,right);
}
}
int main()
{
srand(time(NULL));
int A[N];
for(int i=0;i<N;i++)
{
A[i]=rand()%100;
printf("%d ",A[i]);
}
printf("\n");
int K;
scanf("%d",&K);
buildMinHeap(A,0,K-1);//先取前K个数建立一个小顶堆
//然后拿堆顶和后面[K,N-1]个元素比较
for(int i=K;i<N;i++)
{
//比堆顶大就接着比下一个,比堆顶小就换掉堆顶
if(A[i]>A[0])
{
SWAP(A[i],A[0]);
adjustMinHeap(A,0,K-1);//调整为小顶堆
}
}
//最终小顶堆里的元素就是前K大的数,堆顶就是第K大的数
printf("第%d大的数:%d\n",K,A[0]);
return 0;
}
③多机查找法(赛马淘汰法)