Top_K问题,堆排序

Top_K问题
简述:在大量数据中选出K个最大的或最小的。
以取K个最大数为例:
具体思路:
1. 将给定的数据的前K个元素压入到vector空间,对这K个数进行向下调整建小堆;
2. 再将堆顶元素和数组的其他元素进行比较,当堆顶元素小于数组中所取元素时,将所取数组元素入堆;
3. 再进行调整,直到数组所有元素都依次进行比较。

//仿函数比较
template<class T>
struct Less
{
    bool operator()(const T& l, const T& r)
    {
        return l < r;
    }
};
template<class T>
struct Greator
{
    bool operator()(const T& l, const T& r)
    {
        return l > r;
    }
};

template<class T,class Compare >
class K_Heap
{
public:
    K_Heap()
    {}
    K_Heap(T* arr, size_t size, size_t k)
    {
        assert(k < size);
        _a.reserve(k);
        for (size_t i = 0; i < k; ++i)
        {
            _a.push_back(arr[i]);
        }
        for (size_t i = (k - 2) / 2; i > 0; --i)
        {
            AdjustDown(k, i);
        }
        for (size_t i = 0; i < size; ++i)
        {
            if (_a[0] < arr[i])
            {
                _a[0] = arr[i];
                AdjustDown(k, 0);
            }
        }
        for (size_t i = 0; i < k; ++i)
        {
            cout << _a[i] << " ";
        }
        cout << endl;
    }
protected:
    void AdjustDown(size_t k, size_t parent)
    {
        Compare com;
        size_t child = parent * 2 + 1;
        while (child < _a.size())
        {
            if (child + 1 < _a.size() && com(_a[child+1], _a[child]))
            {
                ++child;
            }
            if (com(_a[child], _a[parent]))
            {
                swap(_a[child], _a[parent]);
                parent = child;
                child = parent * 2 + 1;
            }
            else
            {
                break;
            }
        }
    }
private:
    vector<T> _a;
};

堆排序:

具体思路:
1. 将给定的数组压入vector中,对其进行向下调整调节为大堆或者小堆;
2.取出最小的数和最大数进行交换;
3.再次进行调整的时候元素的个数应该减一,不用算最后一个元素(因为最后一个不是最大的数就是最小的数);
4.直到所有的数都依次进行了比较。

//堆排序
template<class T>
struct Less
{
    bool operator()(const T& l, const T& r)
    {
        return l < r;
    }
};
template<class T>
struct Greator
{
    bool operator()(const T& l, const T& r)
    {
        return l > r;
    }
};
template<class T, class Compare>
class Sort_Heap
{
public:
    Sort_Heap()
    {}
    Sort_Heap(T* arr, size_t size)
    {
        _a.reserve(size);
        for (size_t i = 0; i < size; ++i)
        {
            _a.push_back(arr[i]);
        }
        for (int i = (size - 2) / 2; i >= 0; --i)
        {
            AdjustDown(size, i);
        }
    }
    void AdjustDown(size_t size, size_t parent)
    {
        Compare com;
        size_t child = parent * 2 + 1;
        while (child < size)
        {
            if (child + 1 < size && com(_a[child + 1], _a[child]))
            {
                ++child;
            }
            if (com(_a[child], _a[parent]))
            {
                swap(_a[child], _a[parent]);
                parent = child;
                child = parent * 2 + 1;
            }
            else
            {
                break;
            }
        }
    }
    void _Sort_Heap(size_t size)
    {
        size_t end = size - 1;
        while (end > 0)
        {
            swap(_a[0], _a[end]);
            AdjustDown(end, 0);
            --end;
        }
    }
    void Print()
    {
        for (size_t i = 0; i < _a.size(); ++i)
        {
            cout << _a[i] << " ";
        }
        cout << endl;
    }
private:
    vector<T> _a;
};
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值