有一个记分板需要由以下两个操作维护和支持:
void insert(string playerName, int score);
list<string> getPlayersByRank(int rank);
插入功能可以插入playerName及其得分,或者在玩家已经出现在记分牌中的情况下更新玩家的得分。
提供数据结构以支持上述两个操作,使其尽可能最佳。这两个函数都会被频繁调用。
答案 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))
插入或删除节点时,请更新平衡和重量信息(有多少个左右儿童)。更新分数时,删除节点并重新插入新分数。