版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wzc2608/article/details/81184179
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
void swap(vector<int>& arr, int i, int j)
{
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
void heapInsert(vector<int>& arr, int value, int index)
{
arr[index] = value;
while(index != 0)
{
int parent = (index - 1) / 2;
if(arr[parent] < arr[index])
{
swap(arr, parent, index);
index = parent;
}
else
break;
}
}
void heapfi(vector<int>& arr, int index, int heapSize)
{
int left = index * 2 + 1;
int right = index * 2 + 2;
int largest = index;
while(left < heapSize)
{
if(arr[left] > arr[index])
largest = left;
if(right < heapSize && arr[right] > arr[largest])
largest = right;
if(largest != index)
swap(arr, largest, index);
else
break;
index = largest;
left = index * 2 + 1;
right = index * 2 + 2;
}
}
vector<int> getMin(vector<int>& arr, int k)
{
if(k < 1 || k > arr.size())
return arr;
vector<int> kheap(k);
for(int i = 0; i != k; i++)
heapInsert(kheap, arr[i], i);
for(int i = k; i < arr.size(); ++i)
{
if(arr[i] < kheap[0])
{
kheap[0] = arr[i];
heapfi(kheap, 0, k);
}
}
return kheap;
}
//以下是BFPRT算法,时间复杂O(n)
vector<int> partiti(vector<int>& arr, int beg, int end, int pivotValue)
{
int small = beg - 1;
int cur = beg;
int big = end + 1;
while(cur != big)
{
if(arr[cur] < pivotValue)
swap(arr, ++small, cur++);
else if(arr[cur] > pivotValue)
swap(arr, --big, cur);
else
++cur;
}
vector<int> rang(2);
rang[0] = small + 1;
rang[1] = big - 1;
return rang;
}
void insertionsort(vector<int>& arr, int beg, int end)
{
for(int i = beg + 1; i != end + 1; ++i)
for(int j = i; j != beg; --j)
{
if(arr[j - 1] > arr[i])
swap(arr, j - 1, i);
else
break;
}
}
int getMedian(vector<int>& arr, int beg, int end)
{
insertionsort(arr, beg, end);
int sum = end + beg;
int mid = (sum / 2) + sum % 2;
return arr[mid];
}
int select(vector<int>& arr, int beg, int end, int i);
int mideanOfMe(vector<int>& arr, int beg, int end)
{
int num = end - beg + 1;
int offest = num % 5 == 0 ? 0 : 1;
vector<int> marr(num / 5 + offest);
for(int i = 0; i < marr.size(); ++i)
{
int begi = beg + i * 5;
int endi = begi + 4;
marr[i] = getMedian(arr, begi, min(endi, end));
}
return select(marr, 0, marr.size() - 1, marr.size() / 2);
}
int select(vector<int>& arr, int beg, int end, int i)
{
if(beg == end)
return arr[beg];
int pivot = mideanOfMe(arr, beg, end);
vector<int> pivotRange = partiti(arr, beg, end, pivot);
if(i >= pivotRange[0] && i <= pivotRange[1])
return arr[i];
else if(i < pivotRange[0])
return select(arr, beg, pivotRange[0], i);
else
return select(arr, pivotRange[1] + 1, end, i);
}
int getMinkthbyBFPRT(vector<int>& arr, int k)
{
vector<int> res = arr;
return select(res, 0, res.size() - 1, k - 1);
}
vector<int> getMinK(vector<int>& arr, int k)
{
if(k < 1 || k > arr.size())
return arr;
int minKth = getMinkthbyBFPRT(arr, k);
vector<int> res(k);
int index = 0;
for(int i = 0; i != arr.size(); ++i)
if(arr[i] < minKth)
res[index++] = arr[i];
for(; index != res.size(); ++index)
res[index] = minKth;
return res;
}
int main()
{
int a[] = {1, 1, 2, 3, 4, 4, 3, 5, 2};
vector<int> ivec(a, a + 9);
vector<int> arr = getMin(ivec, 5);
for(int i = 0; i < arr.size(); ++i)
cout << arr[i] << " ";
cout << endl;
arr = getMinK(ivec, 5);
for(int i = 0; i < arr.size(); ++i)
cout << arr[i] << " ";
}