我被华金昆卡阿贝拉阅读this great article。他谈到使用红黑树实现一张表,而不是一个双向链表。红黑树编辑文本
我有一些麻烦,理解如何,这可能涉及到发生着变化的缓冲区。例如,拿这两个缓冲器(原件,附加):
Hello!\0 Original
y Append
而且我们说这块表看起来像这样:
Hey!\0
:
buffer start length
original 0 2
original 5 2
append 0 1
我们应该结束了使用双向链表,实现这一点的一种像这样:
------------------ ------------------- ----------------
Buffer = ORIGINAL| |Buffer = ORIGINAL| |Buffer = APPEND
Start = 0 |<--|Start = 5 |<--|Start = 0
Length = 2 | |Length = 2 | |Length = 1
Next = 0x01 |-->|Next = 0x02 |-->|Next = NULL
Previous = NULL | |Previous = 0x01 | |Previous = 0x01
------------------ ------------------- ----------------
如果该文件最初是作为char数组加载的,或者其他东西,编辑之后,这似乎非常简单快速。在另一方面,据我的理解,红黑树应该是这样的:
------------------
size = 2
size_left = 1
size_right = 2
colour = black
------------------
/ \
/ \
/ \
---------------- ----------------
size = 1 size = 2
size_left = 0 size_left = 0
size_right = 0 size_right = 0
colour = red colour = red
---------------- ----------------
/ \ / \
/ \ / \
NULL NULL NULL NULL
我没有看到一个明确的方式编辑后重新喷涂文档的其余部分。当然,插入/删除/查找将会更快地将部分添加到树中。但我错过了如何构建编辑缓冲区以供查看。
我错过了什么?如果我有一个编辑器,并且我删除/插入了一段文本,我将如何遍历该树来重新绘制缓冲区并正确反映该编辑?而且,这将如何比链表提供的O(n)时间复杂度更快?
@rici我想我主要理解树的工作原理,我只是不明白,在这个特定的上下文中(重新绘制缓冲区以反映变化),它具有优势。维基百科确实有一个很好的解释,但它不包括这个话题。我找不到任何其他资源来回答我的问题,所以我在这里问了他 –
我明白这一点;我不明白的是如何通过遍历树来反映所做的更改。使用双向链表,这是非常清楚的;每个节点指向原始位置和追加缓冲区,并且通过保持每个条目长度的运行总和,对节点所做的任何更改都可以通过遍历列表来反映:即通过选择打印来自原始缓冲区或附加缓冲区的某个位置和长度。对树来说,这是如何实现的对我而言并不清楚。但是,我确实理解轮换/必须“修复”树。 –
我认为我最大的问题是努力想通过一个例子。考虑到存储在树中的信息(在上面的例子中,或者其他例子中),我将会看到如何构建一个新的缓冲区。从概念上讲,在我看来,使用链表来构建一个缓冲区将花费O(N)。但是,对于树的等价操作不会采用O(NlogN)吗?因为,对于N件,它需要O(logN)来检索它的信息? –