排行榜的高效数据结构

时间:2013-03-11 06:12:02

标签: algorithm data-structures

我想实现一个排行榜,我意识到尽管这似乎是一个简单的任务,但这可能变得非常复杂。我可以简单地使用具有适当索引的数据库,但我想知道是否有一个有效的数据结构可以支持以下操作。

  • 为给定玩家添加分数
  • 检索给定玩家的最佳得分
  • 检索给定玩家的排名
  • 检索当前玩家等级高于和低于分数的玩家
  • 支持不同的时间范围:今天的分数,本周,今年等等。
  • 可扩展至约100,000名玩家
  • 内存占用尽可能小(即在便宜的机器上运行)

感谢您的帮助!

2 个答案:

答案 0 :(得分:0)

您可以使用二叉搜索树(AVL或红黑等平衡搜索树)根据总分存储玩家信息。在播放器结构中,您可以为不同的时间帧设置不同的数组,并为总分和最佳分数提供单独的变量。找到排名或低于或高于特定玩家的玩家将需要按顺序遍历。

答案 1 :(得分:0)

解决方案是使用两个数据结构。更新操作不仅将O(n)视为给定玩家,还必须重新计算所有玩家的排名。

We will use two DS for this:
    a. Balanced Binary Search Tree
    b. Hash Map

Each node of a Binary Search Tree is [Uid, Score, Reverse-rank]
    Uid: is the user id of a player.
    Score: is the score of a player.
    Reverse-rank: This is a rank of a player but in reverse order. The player scoring lowest will
    have this value as 1. The player scoring highest will have this value as the size of a BST.

    The Binary Search Tree is implemented based on the score of a player.

The Hash Map structure is as follows:
    Key: Uid
    Value: BST Node.

updateRank(userId, score)
    if player is new (userid not in map)
        1. Insert the player in a BST.
        2. Insert the player in a Map.
        3. Calculate Rank: If a node is inserted to right, then its rank will be one less than its
        parent. If a node is inserted to left, then its rank will be one more than its parent.

    if player is old (userid exists in map)
        1. Fetch the node from Map.
        2. if new score and old score is same then do nothing.
        3. Delete the old node.
        4. Insert the new node.
        5. Calculate Rank: Perform in-order and mark all the nodes from 1 to n (length).
           This op is expensive among all. It takes O(n)
    O(n)

getRank(userId)
    Find a node from the map.
    return rank as (n + 1) - reverse rank
    O(1)

display()
    Perform inorder traversal and return all the players.
    O(n)

NOTE: 1. The tree has to be balanced BST.
      2. We cannot use heap because, the display() would be difficult to implement. We would have
      to remove every element from heap which would take O(nlogn).