zoukankan      html  css  js  c++  java
  • 堆的应用之海量数据处理(红包大乱战)

    应用场景:2015年春节期间,A公司的支付软件某宝和T公司某信红包大乱战。春节高峰以后,公司Leader要求后台攻城狮对后台的海量的数据进行分析。先要求分析出各地区发红包最多的前100位用户。现在知道人最多的S地区大约有100W用户,要求写一个算法实现。

    分析:看到这里,问题可以简化为求很多个数据中的前100个节点,然而这很多个数据磁盘根本放不下,并且找出前100个数比较复杂,因此我们可以借助堆来实现。这样数据从磁盘里读,而内存中只有100个数据。那么到底是建大堆还是建小堆来解决呢?我们知道大堆就是父节点都大于孩子节点,小堆就是父节点都小于孩子节点,当我们找到的数大于最后一个节点时堆就应该排序一次,因此我们应该建一个小堆,根节点就是100里面最小的,用父节点与需要比较的数据进行比较,如果比根节点大,那么需要入堆进行排序,否则就不需要排序。实现代码如下:

    void CreateRedPacket(vector<int>& moneys)  //创建红包数据
    {
        srand(time(0));
        moneys.reserve(N);
        for (int i = 0; i < N; ++i)
        {
            moneys.push_back(rand() % 10000);
        }
        for (int j = N - K; j < N; ++j)
        {
            moneys[j] = rand() % N;
        }
    }

    void AdjustDown(int*a, size_t size, int root)    //向下调整
    {
        int parent = root;
        int child = parent * 2 + 1;
        while (child < size)
        {
            while (child + 1 < size&&a[child + 1] > a[child])   //找出左右节点中值最大的那个
                child++;

            if(a[parent] < a[child])
            {
                swap(a[parent], a[child]);
                parent = child;
                child = parent * 2 + 1;
            }
            else
            {
                break;
            }
        }
    }

    void GetTopK(vector<int>& moneys)   //获取前K个数据
    {
        int arrays[K] = { 0 };
        for (size_t i = 0; i < K; ++i)
        {
            arrays[i] = moneys[i];
        }

        for (int i = (K- 2) / 2; i>=0; ++i)   //先建一个数据个数为K的堆
        {
            AdjustDown(arrays, K, 0);
        }

        for (size_t i = K; i < N; ++i)    //把剩下的数据一一跟对顶元素比较,如果数据小于堆顶元素就赋值给堆顶元素并向下调整
        {
            if (arrays[0] < moneys[i])
            {
                arrays[0] = moneys[i];
                AdjustDown(arrays,  K, i);
            }
        }
        for (int i = 0; i < K; ++i)   //打印出前K个数据
        {
            cout << arrays[i] << "  ";
        }
        cout << endl;
    }

    void TestTopK()
    {
        vector<int> moneys;
        CreateRedPacket(moneys);
        GetTopK(moneys);
    }

  • 相关阅读:
    Aseprite+Cocos:打包像素画图,导入到cocos里并动起来
    自定义博客园个人皮肤
    埃航和737MAX坠毁:软件优先级问题
    淘宝网——软件质量属性场景分析
    王概凯《架构漫谈》阅读笔记
    2965 -- The Pilots Brothers' refrigerator
    UVa10082 -- WERTYU
    1753 -- Flip Game
    1083 -- Moving Tables
    2159 -- Ancient Cipher
  • 原文地址:https://www.cnblogs.com/qingjiaowoxiaoxioashou/p/5951589.html
Copyright © 2011-2022 走看看