有人的地方就有对比,游戏中自然也少不了排行榜。
当前项目设计目标是,每个服务器玩家数量为百万左右。每个玩家都有战力、经验等属性,战力最大值在50万以内。
现在期望能有战力排行榜,有以下几点需求:
全部角色参与排行,能实时知道某个角色的排名
排行榜显示前100名玩家详情
排名规则是战力越高排名越前,战力相同则比较经验,经验再相同则比较创建时间。
排行榜算法并不少见,这篇文章介绍的就不错。根据上述需求分析,最适合采用文中的算法3,即树形分区设计,具体算法文中有详细介绍。
采用该算法,时间复杂度在O(log(n)),在百万规模下空间消耗也就几十M。但有两个问题待解决:
战力相同时如何确定具体排名
如何获得TOP N
针对问题1,假定游戏设计的战力相对均匀(尽管高战力显然更分散),那么战力相同的玩家数量会在一个较小规模内。依然以战力构建排行树,相同战力为同一个节点。节点可以存在一个有序列表,以经验、创建时间排序。这里有个小技巧,以玩家ID等效于创建时间,就直接记录了相应玩家,同时也保证了唯一性。这在增加删除(排名改变时)尤为有用。
针对问题2,排行树算法决定了最终战力节点都是叶子节点,同时在叶子节点层,战力总是从左向右递增的。在树构建过程中,可以分别使用一个前向和后向节点,将所有叶子节点连成一个双向链表。这样就可以做到既能得到前N名,也可以得到后N名,时间复杂度都是O(N)。
下面show the code,完整代码请参看文末。
public class LeaderboardTree{
class LeaderboardNode{
public int lowerKey = 0;
public int upperKey = 0;
public int number = 0;
public ArrayList extraList = new ArrayList();
public LeaderboardNode left = null;
public LeaderboardNode right = null;
public LeaderboardNode prev = null;
public LeaderboardNode next &#