基于堆排序
// topK.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include
#include
using namespace std;
void adjustHeap(vector<int>& arr, int begin,int end) //下沉,维护小根堆
{
int dad = begin, son = 2 * dad + 1;
while (son <= end){
if (son + 1 <= end&&arr[son] > arr[son + 1]) son++;
if (arr[dad] < arr[son]) return;
else{
swap(arr[dad], arr[son]);
dad = son;
son = 2 * dad + 1;
}
}
}
void creatHeap(vector<int>& arr, int len)
{
for (int i = len / 2 - 1; i >= 0; i--){
adjustHeap(arr, i, len - 1);
}
}
int main()
{
int k = 5;
vector<int> nums = { 3,1,6,8,2,0,4,66,12 };
vector<int> heap; //始终要维护的堆
for (int i = 0; i < k; ++i) //加入k个数建堆
{
heap.push_back(nums[i]);
}
creatHeap(heap, k);
for (int i = k; i < nums.size(); i++){ //新来的数字与堆顶比较,如果大于堆顶元素就替换掉它,再重新下沉维护小根堆
if (nums[i]>heap[0]){
heap[0] = nums[i];
adjustHeap(heap, 0, k - 1);
}
}
//输出前k大的所有k个数
for (int i = 0; i < heap.size(); i++)
{
cout << heap[i] << " ";
}
//输出第k大的数
cout << heap[0] << endl;
return 0;
}
时间复杂度O(nlogK),n是所有数字个数,K是堆大小
基于快排
// topK.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include
#include
using namespace std;
int Partition(vector<int> &nums, int left, int right){ //分区,返回基准数字的索引
int key = nums[left];
int i = left, j = right;
while (i < j){
while (i < j&&nums[j] <= key) j--;
nums[i] = nums[j];
while (i < j&&nums[i] >= key) i++;
nums[j] = nums[i];
}
nums[i] = key;
return i;
}
int qSearch(vector<int>& arr, int left, int right, int k){
//只排序固定区间的前k个数
int pos = -1, len = 0; //len指的是目前取到了前多少个数
int i = left, j = right;
if (i < j){
pos = Partition(arr, i, j);
len = pos - i + 1; //是包括本身的长度
if (len < k){
pos = qSearch(arr, pos + 1, right, k - len);
}
else if (len>k){
pos = qSearch(arr, left, pos - 1, k);
}
}
return pos;
}
int main(){
vector<int> nums{ 1, 45, 2, 3, 46, 0, 44, 6,12,456677,23,12,22,-10,444444,132422 };
int k = 3;
qSearch(nums, 0, nums.size() - 1, k);
for (int i = 0; i < k; i++){
cout << nums[i] << endl;
}
}
时间复杂度O(n)
面试常考的,一定要会啊!