文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>100题_05 查找最小的k个元素

100题_05 查找最小的k个元素

时间:2011-03-04  来源:小橋流水

不多说了,这个题是一个老题了,最简单的办法就是用大顶堆了,每次遍历数组与堆顶元素进行比较,如果比堆顶小,就替换堆顶,继续调整为大顶堆。

 

代码如下:

View Code #pragma once
#include <cstdlib>

using namespace std;

template <typename T>
class MaxHeap
{
public:
    MaxHeap(int size = 10)
    {
        this->size = size;
        data = new T[size];
        cur = 0;
    }

    MaxHeap(T a[], int size)
    {
        this->size = size;
        data = new T[size];
        for (int i = 0; i < size; i++)
            data[i] = a[i];
        cur = size;
        BuildHeap();
    }

    T RemoveMax()
    {
        if (IsEmpty())
            throw "heap is empty";
        else
        {
            T temp = data[0];
            data[0] = data[--cur];
            if (cur > 0)
                ShiftDown(0);
            return temp;
        }
    }

    void ReplaceMax(const T& value)
    {
        if (IsEmpty())
            throw "heap is empty";
        else
        {
            data[0] = value;
            ShiftDown(0);
        }
    }

    T PeekMax()
    {
        if (IsEmpty())
            throw "heap is empty";
        else
            return data[0];
    }

    bool Insert(const T& value)
    {
        if (IsFull())
            return false;
        else
        {
            data[cur++] = value;
            ShiftUp(cur - 1);
            return true;
        }

    }

    bool IsFull()
    {
        return cur == size;
    }

    bool IsEmpty()
    {
        return cur == 0;
    }

    ~MaxHeap()
    {
        delete[] data;
    }
private:
    int size;
    int cur;
    T * data;

    int LeftChild(int pose) const
    {
        return 2*pose + 1;
    }

    int RightChild(int pose) const
    {
        return 2*pose + 2;
    }

    int Parent(int pose) const
    {
        return (pose - 1) / 2;
    }

    // 从pose的位置向下调整
    void ShiftDown(int pose)
    {
        int i = pose;
        int j = LeftChild(i);
        T temp = data[i];
        while (j < cur)
        {
            if (j < cur - 1 && data[j] < data[j+1])
                j++;
            if (temp < data[j])
            {
                data[i] = data[j];
                i = j;
                j = LeftChild(j);
            }
            else
                break;
        }
        data[i] = temp;
    }

    void ShiftUp(int pose)
    {
        int tempPose = pose;
        T temp = data[tempPose];
        while (tempPose > 0 && data[Parent(tempPose)] < temp)
        {
            data[tempPose] = data[Parent(tempPose)];
            tempPose = Parent(tempPose);
        }
        data[tempPose] = temp;
    }

    void BuildHeap()
    {
        for (int i = cur/2 -1; i >= 0; i--)
            ShiftDown(i);
    }
};

 

View Code #include "MaxHeap.h"
#include <iostream>

using namespace std;

int *min(int a[], int n, int k) // 找出数组中前k个最小的
{
    MaxHeap<int> mh(k);
    int i;
    for (i = 0; i < k; i++)
        mh.Insert(a[i]);
    for (; i < n; i++)
    {
        int max = mh.PeekMax();
        if (a[i] < max)
            mh.ReplaceMax(max);
    }
    int *result = new int[k];
    for (i = k -1; i >= 0; i--)
    {
        result[i] = mh.RemoveMax();
    }
    return result;
}

int main()
{
    int a[] = {5,3,7,2,6,8,4,9,19,50,18,16};
    int *x = min(a, 12, 5);
    for (int i = 0; i < 5; i++)
        cout<<x[i]<<' ';
    cout<<endl;
    delete[] x;
    return 0;
}
相关阅读 更多 +
排行榜 更多 +
别惹神枪手安卓版

别惹神枪手安卓版

冒险解谜 下载
坦克战争世界

坦克战争世界

模拟经营 下载
丛林反击战

丛林反击战

飞行射击 下载