支持记分板最佳操作的数据结构

时间:2013-05-15 10:51:23

标签: algorithm data-structures

有一个记分板需要由以下两个操作维护和支持:

void insert(string playerName, int score);
list<string> getPlayersByRank(int rank); 

插入功能可以插入playerName及其得分,或者在玩家已经出现在记分牌中的情况下更新玩家的得分。

  

提供数据结构以支持上述两个操作,使其尽可能最佳。这两个函数都会被频繁调用。

1 个答案:

答案 0 :(得分:1)

作业?

一个平衡的二进制树让人想起,因为它为你提供了O(log(n))插入和(O(n))有序遍历。

检查AVL树,例如:http://en.wikipedia.org/wiki/AVL_tree

编辑:

非常感谢tmyklebu的提交,我意识到我忽略了你的getPlayersByRank接受一个参数的事实,所以它是按排名而不是完整的遍历进行查找。

该方法仍然有效,但您应该使用一个变量,其中每个节点都知道它在每个分支中有多少个后代。这样,您可以直接下降到所需的等级。

示例:

(<P1S1L1R1> = Player 1 Score 1 Left 1 Right 1)

             <P1S6L3R2>
            /            \
      <P2S8L1R1>        <P5S3L0R1>
      /        \           \
<P3S10L0R0>    <P4S8L0R0>    <P6S1L0R0>

现在,从这棵树中,如果你想让所有玩家排名第二,你只需要查看根,看看有三个左节点,所以根节点(P1)的玩家排名第四。您将向左下移到P2并看到只有一个左节点,因此P2排名第二。但是,为了让所有球员排名第二,你仍然需要向右下方找到P4,他们也有相同的分数(假设同样得分的球员总是插在右边)。

所以每个节点的当前排名是:

 (rank of parent node) + (number of left children) 
    + (0 if (score is the same as score of parent node) or
       1 otherwise))

插入或删除节点时,请更新平衡和重量信息(有多少个左右儿童)。更新分数时,删除节点并重新插入新分数。