通向码农的道路(开源 libevent min_heap 实现)

来源:互联网 发布:二手车交易发票软件 编辑:程序博客网 时间:2024/05/17 02:29
以前项目,我们在对应timer事件 ,传统都采取的 每帧循环  遍历队列所有数据,检测是否满足条件。
比如( 海盗奇兵,部落冲突 ,都存在建筑升级,那么服务器再跑的时候 我如何知道,每个建筑什么时候升级成功,那我们只有每秒判断一次,但是这样的效率实在太低,如果每次服务器只需要判断一个节点?就知道所有事件,是否那些满足? 那么最小堆当之无愧了,我还是认为,服务器最终还是算法与数据结构问题,哪怕架构,设计模式再漂亮,优秀,再海量数据,高并发网络环境,显得总是那么无能为力)

性能分析:
 
最小堆插入最坏情况是logN次  ,最小堆的最大缺点就在于必须是连续的内存  。
 
最大优势 取最小值性能是O(1), 如果插入的数据基本有序,那么最小堆能获得比较好的性能, 在频繁不断地取最小值的是否满足条件的应用中有更加好的性能(如超时队列,所谓的优先队列)

以下是c++ 模版实现 centos7.0 编译通过


#include <iostream>
#include <stdio.h>
using namespace std;

struct Test
{
    bool operator < (Test const &other)const
    {
        return other.x > this->x;
    }
    
    bool operator > (Test const &other)const
    {
        return other.x < this->x;
    }
    
    void  operator = (Test &other)
    {
        this->x = other.x;
    }
    bool operator <= (Test const &other)const
    {
        return other.x > this->x;
    }
    
    int x;
    int y;
}test;


template<class T>
class MinHeap {
public:
    MinHeap(int MinHeapSize = 10);
    ~MinHeap() {delete [] heap;}
    int Size() const {return CurrentSize;}
    T Min() {if (CurrentSize == 0)
        return heap[1];}
    void  Insert (T& x);
    MinHeap<T>& DeleteMin(T& x);
    void Initialize(T a[], int size, int ArraySize);
    void Deactivate() {heap = 0;}
    void Output() const;
    T Get(int i)const
    {
        return heap[i];
    }
    
private:
    int CurrentSize, MaxSize;
    T *heap;
};


template<class T>
MinHeap<T>::MinHeap(int MinHeapSize)
{
    MaxSize = MinHeapSize;
    heap = new T[MaxSize+1];
    CurrentSize = 0;
}

template<class T>
void MinHeap<T>::Insert(T& x)
{
    if (CurrentSize == MaxSize)
    {
        return;//throw NoMem();
    }
    
    //为x寻找应插入的位置
    //i从新的叶节点开始,并沿着树上升
    int i = 0;
    i = ++CurrentSize;
    while (i != 1 && x < heap[i/2])
    {
        heap[i] = heap[i/2]; // 将元素下移
        i /= 2;              // 移向父节点
    }
    heap[i] = x;
}

template<class T>
MinHeap<T>& MinHeap<T>::DeleteMin(T& x)
{
    if (CurrentSize == 0)
        //throw OutOfBounds();
        
        x = heap[1];
    
    T y = heap[CurrentSize--]; //最后一个元素
    
    // 从根开始, 为y寻找合适的位置
    int i = 1,  // 堆的当前节点
    ci = 2;  // i的子节点
    
    while (ci <= CurrentSize)
    {
        // 使heap[ci] 是i较小的子节点
        if (ci < CurrentSize
            && heap[ci] > heap[ci+1])
            ci++;
        
        // 能把y放入heap[i]吗?
        if (y <= heap[ci])
            break;  // 能
        
        // 不能
        heap[i] = heap[ci]; // 子节点上移
        i = ci;             // 下移一层
        ci *= 2;
    }
    
    heap[i] = y;
    
    return *this;
}

template<class T>
void MinHeap<T>::Initialize(T a[], int size, int ArraySize)
{
    delete [] heap;
    heap = a;
    CurrentSize = size;
    MaxSize = ArraySize;
    
    // 产生一个最小堆
    for (int i = CurrentSize/2; i >= 1; i--)
    {
        T y = heap[i]; // 子树的根
        
        // 寻找放置y的位置
        int c = 2*i; // c 的父节点是y的目标位置
        
        while (c <= CurrentSize)
        {
            // 使heap[c]是较小的子节点
            if (c < CurrentSize &&
                heap[c] > heap[c+1]) c++;
            
            // 能把y放入heap[c/2]吗?
            if (y <= heap[c]) break;  // 能
            
            // 不能
            heap[c/2] = heap[c]; // 子节点上移
            c *= 2;              // 下移一层
        }
        
        heap[c/2] = y;
    }
}

template<class T>
void MinHeap<T>::Output() const
{
    cout << "The " << CurrentSize
    << " elements are"<< endl;
    for (int i = 1; i <= CurrentSize; i++)
        cout << heap[i]<< ' ';
    cout << endl;
}

int main()
{
    MinHeap<Test> min_heap;
    Test t,t1,t2;
    t.x = 10;
    t.y = 10;
    
    t1.x = 11;
    t1.y = 11;


    t2.x = 12;
    t2.y = 12;
    
    min_heap.Insert(t);
    min_heap.Insert(t1);
    min_heap.Insert(t2);
    
    min_heap.DeleteMin(t);
    for(int i = 1; i <= min_heap.Size();i ++)
    {
        auto type = min_heap.Get(i);
        printf("%d\n",type.x);
    }
    return 0;
}

 
0 0
原创粉丝点击