#include<stdio.h>
#include<time.h>
//选择问题解法
//打印数组
void print(int *a,int len){
for(int i=0;i<len;i++){
printf("%d ",*(a+i));
}
}
//交换两个数
void swap(int *a,int *b){
int temp=*a;
*a=*b;
*b=temp;
}
//冒泡
void bubbleSort(int a[],int len){
//这里可以不用全排完,只需排k个最大就行 O(nk)
while((len--)>-1){
for(int i=0;i<len;i++){
if(a[i]<a[i+1]){
swap(&a[i],&a[i+1]);
}
}
}
}
//快排
int quickSort(int a[],int low,int high){
//int low=0,high=len-1;
int pivotkey=a[low];
while(low<high){
while(low<high&&a[high]<=pivotkey) --high;
a[low]=a[high];
while(low<high&&a[low]>=pivotkey) ++low;
a[high]=a[low];
}
a[low]=pivotkey;
//printf("prvotkey%d\n",pivotkey);
//print(a,high+1);
// if(low<high){
// quickSort(a,0,low);
// quickSort(a,low+1,high);
// }
return low;
}
//快排的递归
void Qsort(int a[],int low,int high){
if(low<high){
int temp=quickSort(a,low,high);
Qsort(a,low,temp);
Qsort(a,temp+1,high);
}
}
void Qsort2(int a[],int low,int high,int k){
int temp=quickSort(a,low,high);
int length=temp-low;
//printf(" length:%d temp:%d,k:%d\n",length,temp,k);
if(length==k||length==k-1){
return;
}
if(length<(k-1)){
//在后半段寻找第k-temp-1个数
Qsort2(a,temp+1,high,k-length-1);
}else if(length>(k-1)){
//在前半段寻找k大个数
Qsort2(a,0,temp,k);
}
}
//堆down
void heapDown(int a[],int q,int len){
int left=2*q+1;
int right=2*q+2;
int max=q,min=q;
while(left<len){
//先比较孩子 建小堆
if(right<len&&a[left]>a[right]){
min=right;
}else{
min=left;
}
if(a[min]<a[q]){
}else{
min=q;
}
if(min!=q){
swap(&a[q],&a[min]);
q=min;
left=2*min+1;
right=2*min+2;
}else{
break;
}
//建大堆
// if(right<len&&a[right]>a[left]){
// max=right;
// }else{
// max=left;
// }
// if(a[max]>a[q]){
//
// }else{
// max=q;
// }
// if(max!=q){
// swap(&a[q],&a[max]);
// q=max;
// left=2*max+1;
// right=2*max+2;
// }else{
// break;
// }
}
}
//建堆
void initHeap(int a[],int len){
for(int i=len/2-1;i>-1;i--){
heapDown(a,i,len);
}
}
//堆排
void heapSort(int a[],int len){
initHeap(a,len);
//排序
for(int i=len-1;i>0;i--){
swap(&a[i],&a[0]);
heapDown(a,0,i);
}
}
void heapSort2(int a[],int len,int k){
initHeap(a,k);
for(int i=k;i<len;i++){
if(a[i]>a[0]){
swap(&a[i],&a[0]);
heapDown(a,0,k);
}
}
//便于打印
swap(&a[0],&a[k-1]);
}
//选择排序
void selectedSort(int a[],int len,int k){
for(int i=0;i<k;i++){
int max=i;
for(int j=i+1;j<len;j++){
if(a[j]>a[max]){
max=j;
}
}
if(i!=max)
swap(&a[i],&a[max]);
}
}
//找到第k大的数
void findK(int a[],int len,int k){
printf("打印前:");
print(a,len);
printf("\n");
clock_t start, finish;
start = clock();
//解法一,排序
//冒泡 O(n^2)
//bubbleSort(a,len);
// 用快排 O(nlog2N)
//Qsort(a,0,len-1);
//堆排 O(nlog2N)
//heapSort(a,len);
//选择排序 O(nk) 当k比较小,选择排序比较好 但不稳定
//selectedSort(a,len,k);
//解法二,对快排优化
//优化快排,O(nlog2K)
// Qsort2(a,0,len-1,k);
//解法三,对堆排优化
heapSort2(a,len,k);
//for(int i=0;i<100000000;i++);
print(a,len);
printf("第%d大的数为%d\n",k,a[k-1]);
double duration;
finish = clock();
duration = (double)(finish - start) / CLOCKS_PER_SEC;
printf( "%f seconds\n", duration );
}
int main()
{
int a[]={11,3,15,33,2,5,7,14,15};
findK(a,sizeof(a)/sizeof(int),6);
}