Python 大范围连续整数的数据结构?
假设内存中有一大范围的连续整数,每个整数只属于一个类别。两个操作必须是O(logn):将一个范围从一个类别移动到另一个类别,并查找给定范围的类别计数 我敢肯定,如果第一个操作得到正确的实现,第二个操作就很容易解决了 每个整数从一个类别开始,所以我从一组平衡的BST开始。将子树从一个BST移动到另一个BST(例如,将一个范围移动到另一个类别)的运行时相当于合并两个BST,即O(n1*n2)[] 这太慢了(在python中,C不是一个选项),我无法找到一种方法来利用数据的固有结构来创建一个高效的BST合并操作 我现在看的是AVL、红黑和区间树、二进制堆和treap。比较它们的属性是压倒性的。我应该使用哪种结构 编辑(问题澄清):我可以灵活地存储这些值并创建数据结构。我对如何接收来自另一个应用程序的输入缺乏灵活性,如下所示:Python 大范围连续整数的数据结构?,python,algorithm,tree,computer-science,Python,Algorithm,Tree,Computer Science,假设内存中有一大范围的连续整数,每个整数只属于一个类别。两个操作必须是O(logn):将一个范围从一个类别移动到另一个类别,并查找给定范围的类别计数 我敢肯定,如果第一个操作得到正确的实现,第二个操作就很容易解决了 每个整数从一个类别开始,所以我从一组平衡的BST开始。将子树从一个BST移动到另一个BST(例如,将一个范围移动到另一个类别)的运行时相当于合并两个BST,即O(n1*n2)[] 这太慢了(在python中,C不是一个选项),我无法找到一种方法来利用数据的固有结构来创建一个高效的BS
CATEGORY(cat3,I,J)
。我当前的解决方案为范围内的每个整数创建一个带有节点的树。这对于我的数据集的大小来说太慢了,所以如果有更好的方法,我很乐意重新设计
任何给定的请求都可以将任何可能的整数范围移动到任何类别中。换句话说,范围在
CATEGORY(cat1,1,10)
之后是CATEGORY(cat3,5,15)
的意义上是重叠的,但在任何给定时间,每个整数都将恰好位于一个类别中,这一意义上是不重叠的。您可以拥有以下形式的普通python字典
1 : { "stop" : 5, "category" : "C1"},
6 : { "stop" : 19, "category" : "C23"},
etc
这里的键是范围的起点,值包含范围的终点以及该范围所属的类别
因为字典有固定的访问项目的时间,所以您可以编写一些代码,轻松有效地将一个范围移动到另一个类别:在最坏的情况下,如果您的范围将以前的范围拆分为两个或更多个,您将不得不以某种方式重新构造字典。例如,如果要将(4,8)的范围指定给另一个类别,则最终将得到:
1 : { "stop" : 3, "category" : "C1"},
4 : { "stop" : 8, "category" : "new category"},
9 : { "stop" : 19, "category" : "C23"},
etc
查找类别计数很简单,只需在固定时间内收集所有所需的范围并计算类别
编辑:要成功找到最低(最高)键以开始执行计算/更改,还需要一个包含所有已排序键的普通python列表,以及对分模块。这将有助于在列表中定位索引,以O(logn)时间“放置”范围的开始,然后所有操作都可以在固定时间内完成,除了将新键插入列表所需的O(n)时间(左半部分)。据我所知,您有一个范围[a,B]和表单查询-
1:8
1:4 5:8
1:2 3:4 5:6 7:8
1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8
每个节点将有3个字段[类别、类别计数[],子项更新\u必需=false]
1 5 C1
查询将被分割,节点1:4的类别将设置为C1,子项更新所需项将设置为true,其子项现在不会更新(请记住仅在需要或延迟传播时更新)。节点5:5的类别也将设置为C1
3 4 C2
查询将沿着树向3:4传播(在达到3:4的过程中,1:2和3:4的类别将更新为C1,1:4的子项更新所需将设置为false,1:2和3:4的子项更新所需将设置为true),现在将根据当前需求将3:4的类别更新为C2。接下来,它将为其子级的未来更新(在本例中已设置)设置3:4的children\u update required为true。您可以非常轻松地在连续整数数组上构建树结构,这将有助于使用常量因子。首先将序列重新编号为从0开始,并计算出大于序列范围的二次幂中的最小幂
现在考虑从0到7的整数构成的树,它可以保持为四个数组,每个数组都是水平的。
(all)
0-3 4-7
0-1 2-3 4-5 6-7
0 1 2 3 4 5 6 7
给定一个数字和一个级别,我可以在数组中找到该级别的偏移量,只需根据级别将数字向右移动一个量即可
在每个元素中,我可以放置一个标记,表示“mixed”,或者为树节点上或节点下的每个元素提供类别。我可以通过沿着从树的根到叶子的路径,在我离开时立即停止,来确定节点属于哪一类
1 5000 C5555
1000:5000
|
---------------------
| |
1000:3000 3001:5000
| |
---------------- --------------------
| | | |
1000:2000 2001:3000 3001:4000 4001:5000
1:8
1:4 5:8
1:2 3:4 5:6 7:8
1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8
(all)
0-3 4-7
0-1 2-3 4-5 6-7
0 1 2 3 4 5 6 7
0:cat1 200:cat2 500: cat0 700:cat6 800:cat1