请建议用于表示memory
中记录列表的数据结构。每条记录由以下内容组成:
数据结构应该有效地支持以下操作的实施:
我的主要问题是GetRecord(排名)的有效实施,因为排名可能经常变化。
我想内存DBMS
是一个很好的解决方案,但请不要提出建议;请建议一个数据结构。
答案 0 :(得分:8)
基本上,你只需要一对平衡的搜索树,它将允许O(lg n)插入,删除和getRecord操作。诀窍是,不是将实际数据存储在树中,而是存储指向一组记录对象的指针,其中每个记录对象将包含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引擎完成大部分工作并使您的部分保持简单。