用最小堆查找前几大的数
//最小堆(二叉树的一种)
class Dui
{
    public int[] datas;

    public Dui(int maxLength) {
        if (maxLength <= 0)
        {
            datas = new int[16 + 1];
        }
        else {
            datas = new int[maxLength + 1];
        }
    }

    public void CompareAndReplace(int data) {
        if (data > datas[1]) {
            datas[1] = data;
            SiftDown(1);
        }
    }

    //向下调整
    public void SiftDown(int index) {
        bool isNeedSwap = true;
        int t = index;
            
        //有左儿子
        while (index * 2 <= datas[0] && isNeedSwap) {
            if (datas[index] > datas[index * 2]) {
                t = index * 2;
            }

            //有右儿子
            if (index * 2 + 1 <= datas[0]) {
                if (datas[t] > datas[index * 2 + 1]) {
                    t = index * 2 + 1;
                }
            }

            if (index != t)
            {
                int temp = datas[index];
                datas[index] = datas[t];
                datas[t] = temp;
                index = t;
            }
            else {
                //比左右两儿子都小了
                isNeedSwap = false;
            }
        }
    }

    public void Insert(int val) {
        if (datas.Length - 1 == datas[0]) {
            //我这里就不重构数组了
            Console.WriteLine("最小堆已满!");
            return;
        }

        int insertIndex = datas[0] + 1;
        datas[insertIndex] = val;
        datas[0]++;
        SiftUp(insertIndex);
    }
    
    public override string ToString() {
        string ss = "";
        for (int i = 1; i <= datas[0]; i++) {
            ss += i+":" + datas[i] + "  ";
        }

        return ss;
    }
}

static void Main(string[] args)
{
    Dui dui = new Dui(3);
    int[] datas = { 10, 5, 3, 99, 1, 5, 6, 20, 7, 33 };
    dui.Insert(datas[0]);
    dui.Insert(datas[1]);
    dui.Insert(datas[2]);
    for (int i = 3; i < datas.Length; i++) {
        dui.CompareAndReplace(datas[i]);
    }
    Console.WriteLine(dui);
    Console.ReadKey();
}


利用最小堆根节点的元素为堆中的最小值,先生成一个只有3个元素的堆(假如找前三大的),随机初始化,然后一一比较要寻找的数据和根节点,只要比根节点小的,都不是第三大的数值,如果比根节点数据大,这才舍弃根节点数据替换为当前比较数值,再向下调整,继续比较。


首页 我的博客
粤ICP备17103704号