其實按照上一篇文章的思路,可以根據快排來計算第k大的數。
但會修改數組中的數據,所以這裏有新的不修改數據的思路:
1、用multiset實現自動排序,大小爲k,每個數與set中最大的數比較,如果小於則替換。
2、可以用最大堆來實現,方法類似上面的。關鍵是看代碼註釋在下面。
時間複雜度爲:
#include<iostream>
#include<vector>
#include<set>
using namespace std;
int numbers[100];
//從vector獲取數據
void getnumbers(vector<int>& numbers){
numbers.clear();
int x;
printf("輸入數據:\n");
scanf("%d",&x);
while(x!=-1){
numbers.push_back(x);
scanf("%d",&x);
}
}
//用模板找出第k個數
void templatefindk(const vector<int>& numbers){
int k;
printf("輸入要查找的數\n");
scanf("%d",&k);
multiset<int,greater<int>> Intset;
vector<int>::const_iterator iter = numbers.begin();
//從大到小排序
multiset<int,greater<int>>::iterator intiter;
while(iter != numbers.end()){
if(Intset.size()<k)
Intset.insert(*iter);
else{
intiter = Intset.begin();
if(*iter<*intiter){
Intset.erase(intiter);
Intset.insert(*iter);
}
}
++iter;
}
intiter = Intset.begin();
printf("第%d大的數爲%d\n",k,*intiter);
}
//numbers[beg+1]到numbers[len]爲最大堆,將numbers[beg]插入其中
void heapdown(int *heap,int beg,int len){
int temp = heap[beg];
int i = 2*beg+1;
while(i<=len){
if(i+1 <=len && heap[i]<heap[i+1])
i = i+1;
if(heap[i]<=heap[beg])
break;
heap[beg] = heap[i];
beg = i;
i = 2*beg+1;
}
heap[beg] = temp;
}
//建立最大堆
void buildheap(int *heap,int len){
for(int beg = len/2-1;beg >=0;beg--)
heapdown(heap,beg,len);
}
//用堆找第k大的數
void heapfindk(){
int len =0,x,k;
printf("輸入數組\n");
scanf("%d",&x);
while(x!= -1){
numbers[len++] = x;
scanf("%d",&x);
}
printf("輸入要查找的數位置\n");
scanf("%d",&k);
int *heap = (int *)malloc(sizeof(int)*k);
int i =0;
while(i<k){
heap[i] = numbers[i++];
}
//前k個數建堆
buildheap(heap,k-1);
while(i<=len){
if(numbers[i++]<heap[0])
heapdown(heap,0,k-1);
}
printf("第%d大的數爲%d\n",k,heap[0]);
}
int main(){
vector<int> numbers;
printf("用模板找\n");
getnumbers(numbers);
templatefindk(numbers);
//
printf("用堆來找\n");
heapfindk();
system("PAUSE");
return 0;
}