/***************** n个无序数中求第K大数 *****************/
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
/*冒泡排序思想,时间复杂度:O(n*k)*/
int findK_2(int a[], int k){
bool flag = true;
for(int i=0;i<k && flag;i++){
flag=false;
for(int j=8;j>i;j--){
if(a[j]>a[j-1]){
swap(a[j],a[j-1]);
flag=true;
}
}
}
return a[k-1];
}
/*堆排序思想,时间复杂度:O(nlogk) */
//将a[s...m]调正为堆,其中除s位置值都符合堆定义
void AdjustHeap(int a[], int s, int m){
int j, tmp=a[s];
for(j=s*2;j<=m;j*=2){
if(j<m && a[j]<a[j+1]){
++j;
}
if(a[j]<=tmp){
break;
}
a[s]=a[j];
s=j;
}
a[s]=tmp;
}
int findK_3(int a[], int k){
int len = 9;
//建堆
for(int i=(len-1)/2;i>=0;i--){
AdjustHeap(a, i, len-1);
}
//堆排序
for(int i=len-1;i>=len-k;i--){
swap(a[i], a[0]);
AdjustHeap(a, 0, i-1);
}
return a[len-k];
}
/*快速排序思想,时间复杂度:O(n) */
int Partition(int low, int high, int a[]){
int p = a[low]; //哨兵
while(low<high){
while(low<high && a[high]<=p){
high--;
}
a[low]=a[high];
while(low<high && a[low]>p){
low++;
}
a[high] = a[low];
}
a[low] = p;
return low;
}
int findK_1(int a[], int k, int low, int high){
int tmp = Partition(low, high, a);
if(tmp==k-1){
return a[tmp];
}else if(tmp>k-1){
findK_1(a, k, low, tmp-1);
}else{
findK_1(a, k, tmp+1, high);
}
}
int QuickSort(int a[], int low, int high){
if(low<high){
int tmp = Partition(low, high, a);
QuickSort(a, low, tmp-1);
QuickSort(a, tmp+1, high);
}
}
int main(){
int a[] = {15,3,2,6,1,10,13,11,8};
int b[] = {15,3,2,6,1,10,13,11,8};
int c[] = {15,3,2,6,1,10,13,11,8};
int d[] = {15,3,2,6,1,10,13,11,8};
int k;
cout<<"输入k: ";
cin>>k;
QuickSort(a, 0, 8);
cout<<"快速排序后:"<<endl;
for(int i=0;i<=8;i++){
printf("%d%c",a[i],i!=8?' ':'\n');
}
int big_k_1 = findK_1(b, k, 0, 8);
printf("利用快速排序思想O(n),第%d大的数为:%d\n", k, big_k_1);
int big_k_2 = findK_2(c, k);
printf("利用冒泡排序思想O(n*k),第%d大的数为:%d\n", k, big_k_2);
int big_k_3 = findK_3(d, k);
printf("利用堆排序思想O(nlogk),第%d大的数为:%d\n", k, big_k_3);
return 0;
}