找到无序数组中最小的k个数

版权声明:本文为博主原创文章,未经博主允许不得转载。 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] << " ";
}

猜你喜欢

转载自blog.csdn.net/wzc2608/article/details/81184179