码迷,mamicode.com
首页 > 编程语言 > 详细

最小的K个数 C++(BFPRT,堆排序)

时间:2018-08-05 21:22:56      阅读:121      评论:0      收藏:0      [点我收藏+]

标签:i++   public   swa   ack   cstring   turn   divide   题目   描述   

题目描述

输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。
//堆排序
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
class Solution
{
public:
    void HeapAdjust(vector<int> &a,int s,int n)
    {
        int rc=a[s];
        for(int j=2*s+1; j<=n-1; j=j*2+1)
        {
            if(j<n-1&&a[j]>a[j+1])
                j++;
            if(rc<=a[j])
                break;
            else
            {
                a[s]=a[j];
                s=j;
            }
        }
        a[s]=rc;
    }
    void CreatHeap(vector<int> &a,int n)
    {
        for(int i=n/2-1; i>=0; i--)
        {
            HeapAdjust(a,i,n);
        }
    }
   vector<int> GetLeastNumbers_Solution(vector<int> input, int k)
    {
        vector<int> ans;
        if(input.size()==0||k==0||k>input.size())
            return ans;
        int n=input.size();
        CreatHeap(input,n);
        for(int i=n-1; i>0; i--)
        {
                int x=input[0];
                input[0]=input[i];
                input[i]=x;
                HeapAdjust(input,0,i);
        }
        for(int i=input.size()-1;i>=0&&k>0;i--)
        {
            ans.push_back(input[i]);
            k--;
        }
        return ans;
    }
};
int main()
{
    Solution s;
    int k=4;
    vector<int> ans;
    vector<int> input;
    input.push_back(4);
    input.push_back(5);
    input.push_back(1);
    input.push_back(6);
    input.push_back(2);
    input.push_back(7);
    input.push_back(3);
    input.push_back(8);
    ans=s.GetLeastNumbers_Solution(input,k);
    for(int i=0; i<ans.size(); i++)
    {
        cout<<ans[i];
    }


    return 0;
}
//BFPRT
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
using namespace std;
class Solution {
public:
    vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
        vector<int> ans;
        if(input.size()==0||k==0||k>input.size())
        {
            return ans;
        }
        for(int i=0; i<=BFPRT(input,0,input.size()-1,k); i++)
        {
            ans.push_back(input[i]);
        }
        return ans;
    }
    /* 插入排序,返回中位数下标 */
    int InsertSort(vector<int> &array, int left, int right)
    {
        int temp;
        int j;
        for (int i = left + 1; i <= right; i++)
        {
            temp = array[i];
            j = i - 1;
            while (j >= left && array[j] > temp)
                array[j + 1] = array[j--];
            array[j + 1] = temp;
        }

        return ((right - left) >> 1) + left;
    }

    /* 返回中位数的中位数下标 */
    int GetPivotIndex(vector<int> &array, int left, int right)
    {
        if (right - left < 5)
            return InsertSort(array, left, right);

        int sub_right = left - 1;
        for (int i = left; i + 4 <= right; i += 5)
        {
            int index = InsertSort(array, i, i + 4);  //找到五个元素的中位数的下标
            swap(array[++sub_right], array[index]);   //依次放在左侧
        }

        return BFPRT(array, left, sub_right, ((sub_right - left + 1) >> 1) + 1);
    }

    /* 利用中位数的中位数的下标进行划分,返回分界线下标 */
    int Partition(vector<int> &array, int left, int right, int pivot_index)
    {
        swap(array[pivot_index], array[right]);  //把基准放置于末尾

        int divide_index = left;  //跟踪划分的分界线
        for (int i = left; i < right; i++)
        {
            if (array[i] < array[right])
                swap(array[divide_index++], array[i]);  //比基准小的都放在左侧
        }

        swap(array[divide_index], array[right]);  //最后把基准换回来
        return divide_index;
    }

    int BFPRT(vector<int> &array, int left, int right, const int & k)
    {
        int pivot_index = GetPivotIndex(array, left, right);            //得到中位数的中位数下标
        int divide_index = Partition(array, left, right, pivot_index);  //进行划分,返回划分边界
        int num = divide_index - left + 1;
        if (num == k)
            return divide_index;
        else if (num > k)
            return BFPRT(array, left, divide_index - 1, k);
        else
            return BFPRT(array, divide_index + 1, right, k - num);
    }
};
int main()
{
    Solution s;
    int k=4;
    vector<int> ans;
    vector<int> input;
    input.push_back(4);
    input.push_back(5);
    input.push_back(1);
    input.push_back(6);
    input.push_back(2);
    input.push_back(7);
    input.push_back(3);
    input.push_back(8);
    ans=s.GetLeastNumbers_Solution(input,k);
    for(int i=0; i<ans.size(); i++)
    {
        cout<<ans[i];
    }


    return 0;
}

 

最小的K个数 C++(BFPRT,堆排序)

标签:i++   public   swa   ack   cstring   turn   divide   题目   描述   

原文地址:https://www.cnblogs.com/dshn/p/9426931.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!