存储整数范围的数据结构,查询范围并修改范围

Posted

技术标签:

【中文标题】存储整数范围的数据结构,查询范围并修改范围【英文标题】:Data Structure to store Integer Range , Query the ranges and modify the ranges 【发布时间】:2013-09-27 16:56:38 【问题描述】:

我们需要维护 mobileNumber 及其在内存中的位置。 挑战在于我们拥有超过 500 万用户 存储每个用户的位置就像 500 万条记录的哈希图。 为了解决这个问题,我们必须在范围上工作

我们有一系列电话号码,例如

range1 start="9899123446" end="9912345678" location="a"

range2 start="9912345679" end="9999999999" location="b"

一个数字只能属于一个位置。

我们需要一个数据结构来将这些范围存储在内存中。

它必须支持两个功能

    findLocation(Integer number) 它应该返回位置名称到 属于哪个号码 changeLocation(整数,字符串范围)。它将 Number 的位置从旧位置更改为新位置

这完全是在内存设计中。

我打算使用每个节点包含( startofrange , endofrange ,位置)的树结构。 我将保持节点排序。我还没有完成任何事情。 主要问题是——当第二个改变位置的函数被调用时,比如 9899123448 位置到 b

range1 节点应拆分为 3 个节点 第一个节点 (9899123446,9899123447,a) 第二个节点(9899123448,9899123448,b) 第三个节点(9899123449,9912345678,a)

请提出合适的方法 在此先感谢

【问题讨论】:

【参考方案1】:

通常您可以使用专门的数据结构来存储范围并实现查询,例如Interval Tree。

但是,由于电话号码范围不重叠,您可以将这些范围存储在基于标准树的数据结构中(Binary Search Tree、AVL Tree、Red-Black Tree、B Tree、都可以)仅按 [begin] 排序。

对于 findLocation(number),使用相应的树搜索算法找到第一个 [begin] 值小于该数字的元素,检查其 [end] 值并验证该数字是否在该范围内。如果找到匹配,则返回位置,否则该数字不在任何范围内。

对于changeLocation()操作:

    找到包含数字的旧节点 如果在步骤 1 中找到现有节点,请将其删除并插入新节点 如果未找到现有节点,则插入一个新节点并尝试将其与相邻节点合并。

我假设您使用相同的操作来简单地添加新节点。

更实际的是,您可以将所有条目存储在数据库中,在 [begin] 上建立索引。

【讨论】:

请考虑这样一个事实,即在更改数字的位置时,我必须插入已排序的数组。那太贵了 对不起,我的意思是你应该按 [begin] 对数据进行排序。您可以使用二叉搜索树或更高级的数据结构,如 AVL 树、B 树等。 我将使用平衡二叉搜索树。当调用位置更改操作时。说我有nodeoriginal [10,16,b]。我需要将 13 号的位置更改为 a。我将 nodeoriginal 分解为 3 个节点 node1[10,12,b] node2[13,13,a] node3[14,16,b]。之后将用 node2 替换 nodeoriginal ,它的左孩子是 node1 ,右孩子是 node3 。实现此过程的最佳方法是使树保持平衡 您可以简单地删除旧代码并插入三个新节点。平衡二叉搜索树的算法始终保证它是平衡的 如果 10 到 14 的电话号码用于位置 b,为什么号码 13 会是 a?这种情况真的存在吗?【参考方案2】:

首先range = [begin;end;location]

使用两种结构:

排序数组存储ranges begins 通过begins 访问ends 和locations 的哈希表

应用以下算法:

    使用二分法查找“最接近的”值 ob begin 使用哈希表查找endlocation 以获取begin

【讨论】:

感谢您的建议。我在插入数组时会遇到问题。假设我有 range1 = [1,7,a] range2 = [10,16,b] 。排序后的数组将存储 [1,10] 如果我必须将 5 的位置从 a 更改为 b 。现在范围将是 range1 =[1,4,a] range2 =[5,5,b] range3=[6,7,b] range4[10,16,b] 现在我必须在数组中添加额外的开始最后数组将成为排序数组 [1,5,6,10],因为插入非常昂贵..不能使用列表也会影响搜索... @user2537119 只需将整个 5000000 个范围添加到数组中,然后对其进行排序。 @user2537119 然后如果您将手动添加一些值到排序数组,这不会很慢......你会做多快?每10秒一次? 20 秒?我认为手动插入的插入时间 0.01s 并不慢... 我无法添加整个范围。 要插入排序数组,我必须在插入元素之后移动所有元素

以上是关于存储整数范围的数据结构,查询范围并修改范围的主要内容,如果未能解决你的问题,请参考以下文章

2020-09-01 MySQL 修改表和表字段的类型

优化 MySQL 查询以进行整数范围搜索

应用引擎数据存储中的可用性日期范围查询?

SQL 查询 - 多个日期范围

java基本数据类型存储范围

JAVA四种整数数据类型的取值范围分别是多少