方法一:使用快速排序划分函数partion将数组分为两组:sa和sb
(1)若sa组的个数大于K,则继续在sa分组中找取最大的K个数字 。
(2)若sa组中的数字小于K ,其个数为num,则继续在sb中找取 K-num个最大数字 。
复杂度:N*log2(K);
类似快速排序的partition过程,当参考值随机选取时,复杂度为O(N)
具体参考:http://blog.csdn.net/v_JULY_v/article/details/6370650
具体代码:
1 #include<iostream> 2 #include<stdlib.h> 3 #include<time.h> 4 using namespace std; 5 6 const int N=6; 7 const int K=4; 8 9 int findk(int arr[],int low,int high,int k); 10 int partion(int arr[],int low,int high); 11 12 int main() 13 { 14 int arr[N]={6,3,8,9,4,5}; 15 16 findk(arr,0,N-1,K); 17 18 for(int i=0;i<K;++i) 19 cout<<arr[i]<<ends; 20 21 return 0; 22 } 23 24 int findk(int arr[],int low,int high,int k) 25 { 26 if(low<=high) 27 { 28 int num=partion(arr,low,high); 29 if((num+1)==k) 30 return num; 31 if((num+1)>k) 32 return findk(arr,low,num-1,k); 33 else if((num+1)<k) 34 return findk(arr,num+1,high,k-1-num); 35 } 36 } 37 38 int partion(int arr[],int low,int high) 39 { 40 int tmp=arr[low]; 41 42 while(low<high) 43 { 44 while(arr[high]<tmp&&low<high) 45 --high; 46 if(arr[high]>tmp) 47 { 48 arr[low]=arr[high]; 49 ++low; 50 } 51 while(arr[low]>tmp&&low<high) 52 ++low; 53 if(arr[low]<tmp) 54 { 55 arr[high]=arr[low]; 56 --high; 57 } 58 } 59 arr[low]=tmp; 60 return low; 61 }
方法二:若数据元素很多,不能全部装入内存,可以维持容量为K的最小化堆,堆顶元素就是最大的K个数中的最小数,扫描整个数据;
a.若扫描到的数据大于堆顶元素,替换堆顶元素,更新堆,复杂度(log2(K));
b.若小于,则维持堆不变;
c.扫描下一元素,重复a,b;最后输出堆中元素
算法复杂度:N*log2(K);
具体代码:
1 #include<iostream> 2 using namespace std; 3 4 const int N=10; 5 const int K=5; 6 int arr[N]={6,3,8,9,4,5,11,34,7,1}; 7 8 template<class T> 9 class minHeap 10 { 11 private: 12 int maxSize; 13 int currentSize; 14 T *heapArray; 15 public: 16 minHeap(); 17 void buildHeap(); 18 void shiftDown(int position); 19 T deheap(); 20 void outheap(); 21 void setheap(const T &x); 22 virtual ~minHeap() 23 { 24 delete [] heapArray; 25 } 26 }; 27 28 template<class T> 29 minHeap<T>::minHeap() 30 { 31 currentSize=0; 32 //heapArray[0] is empty 33 maxSize=K+1; 34 heapArray=new T[maxSize]; 35 for(int i=0;i<K;++i) 36 heapArray[i+1]=arr[i]; 37 currentSize=K; 38 buildHeap(); 39 } 40 41 template<class T> 42 void minHeap<T>::buildHeap() 43 { 44 for(int i=currentSize/2;i>0;--i) 45 shiftDown(i); 46 } 47 48 template<class T> 49 void minHeap<T>::shiftDown(int position) 50 { 51 int p=position; 52 int pnum=heapArray[p]; 53 int pson=2*p; 54 55 while(pson<=currentSize) 56 { 57 //the small one 58 if(pson!=currentSize&&heapArray[pson]>heapArray[pson+1]) 59 ++pson; 60 if(heapArray[p]>heapArray[pson]) 61 { 62 heapArray[p]=heapArray[pson]; 63 p=pson; 64 pson=2*p; 65 } 66 else 67 break; 68 } 69 heapArray[p]=pnum; 70 } 71 72 template<class T> 73 T minHeap<T>::deheap() 74 { 75 return heapArray[1]; 76 } 77 78 template<class T> 79 void minHeap<T>::outheap() 80 { 81 for(int i=1;i<=K;++i) 82 cout<<heapArray[i]<<ends; 83 } 84 85 template<class T> 86 void minHeap<T>::setheap(const T &x) 87 { 88 heapArray[1]=x; 89 buildHeap(); 90 } 91 92 int main() 93 { 94 minHeap<int> heap; 95 96 for(int i=4;i<9;++i) 97 { 98 if(arr[i]>heap.deheap()) 99 heap.setheap(arr[i]); 100 else 101 continue; 102 } 103 104 heap.outheap(); 105 106 return 0; 107 }
编程之美——最大的k个数
时间: 2024-11-06 07:17:13