排行榜的高效数据结构,即记录列表(名称,点) - 高效搜索(名称),搜索(排名)和更新(点)

时间:2014-08-09 18:03:09

标签: algorithm list data-structures hashtable record

请建议用于表示memory中记录列表的数据结构。每条记录由以下内容组成:

  • 用户名
  • Rank(基于Points) - 可选字段 - 可以存储在记录中,也可以动态计算

数据结构应该有效地支持以下操作的实施:

  1. 插入(记录) - 可能会更改现有记录的等级
  2. 删除(记录) - 可能会更改现有记录的等级
  3. GetRecord(name) - 可能是哈希表。
  4. GetRecord(评级)
  5. 更新(积分) - 可能会改变现有记录的排名
  6. 我的主要问题是GetRecord(排名)的有效实施,因为排名可能经常变化。

    我想内存DBMS是一个很好的解决方案,但请不要提出建议;请建议一个数据结构。

3 个答案:

答案 0 :(得分:8)

基本上,你只需要一对平衡的搜索树,它将允许O(lg n)插入,删除和getRecord操作。诀窍是,不是将实际数据存储在树中,而是存储指向一组记录对象的指针,其中每个记录对象将包含5个字段:

  1. 用户名
  2. 点值
  3. 指向返回引用对象的名称树中的节点
  4. 指向返回引用该对象的点树中的节点。
  5. 仅在添加新记录和删除记​​录时修改名称树。点树被修改用于插入和删除,但也用于更新,其中找到适当的记录,删除其点树指针,更新其点数,然后将新指针添加到点树。

    如您所愿,如果您愿意,可以使用哈希表代替名称树。这里的关键是你只需将单独的排序索引维护成一组无序的记录,这些记录本身包含指向其索引节点的指针。


    点树将是order statistic tree的一些变体,它不是一个特定的数据结构,而是一个二元搜索树的总称,其操作被修改为维持一个不变量,使得所请求的等级 - 相关操作比走树更有效。不变量如何维护的细节取决于使用的底层平衡搜索树(红黑树,avl树等)。

答案 1 :(得分:2)

跳过列表+散列图应该有效。

以下是Go中的实现:https://github.com/wangjia184/sortedset

集合中的每个节点都与这些属性相关联。

  • key是节点的唯一标识,在您的情况下为“用户名”。
  • value是与节点
  • 关联的任何值
  • score一个数字决定了集合中的顺序(排名),即你案例中的“点数”
  

集合中的每个节点都与一个密钥相关联。钥匙是独一无二的,   分数可能会重复。节点按顺序排列(从低分到   高分)而不是后来订购。如果分数相同,那么   节点按字典顺序按其键排序。中的每个节点   set也可以通过rank来访问,rank代表中的位置   排序集。

     

排序集的典型用例是大规模在线的排行榜   游戏,每次提交新分数时,您都会使用它进行更新   AddOrUpdate()方法。您可以轻松地使用顶级用户   GetByRankRange()方法,您也可以给定用户名返回它   使用FindRank()方法在列表中排名。使用FindRank()和   GetByRankRange()在一起,您可以显示具有类似于a的分数的用户   给定的用户。一切都很快。

答案 2 :(得分:1)

查找包含按顺序记录编号选择记录的功能的DBMS。

请参阅:How to select the nth row in a SQL database table?

构造一个包含UserName列和Points列的表。使UserName成为主索引。在Points上构建次要的非唯一维护索引。

要获得等级为R的记录,请选择点数上的索引并移至记录R.

这使得DBMS引擎完成大部分工作并使您的部分保持简单。