以前项目,我们在对应timer事件 ,传统
都采取的 每帧循环 遍历队列所有数据,检测是否满足条件。
比如( 海盗奇兵,部落冲突 ,都存在建筑升级,那么服务器再跑的时候 我如何知道,每个建筑什么时候升级成功,那我们只有每秒判断一次,但是这样的效率实在太低,如果每次服务器只需要判断一个节点?就知道所有事件,是否那些满足? 那么最小堆当之无愧了,我还是认为,服务器最终还是算法与数据结构问题,哪怕架构,设计模式再漂亮,优秀,再海量数据,高并发网络环境,显得总是那么无能为力)
性能分析:
最小堆插入最坏情况是logN次 , 最小堆的最大缺点就在于必须是连续的内存 。
最大优势 取 最小值性能是O(1), 如果插入的数据基本有序,那么最小堆能获得比较好的性能, 在频繁不断地取最小值的是否满足条件的应用中有更加好的性能(如超时队列,所谓的优先队列)
以下是c++ 模版实现 centos7.0 编译通过
比如( 海盗奇兵,部落冲突 ,都存在建筑升级,那么服务器再跑的时候 我如何知道,每个建筑什么时候升级成功,那我们只有每秒判断一次,但是这样的效率实在太低,如果每次服务器只需要判断一个节点?就知道所有事件,是否那些满足? 那么最小堆当之无愧了,我还是认为,服务器最终还是算法与数据结构问题,哪怕架构,设计模式再漂亮,优秀,再海量数据,高并发网络环境,显得总是那么无能为力)
性能分析:
最小堆插入最坏情况是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;
}