假设我有一个表示这个有序序列的平衡二叉搜索树。
A<B<C<D<E<F<G<H
给定其中一个元素,例如 F,我如何有效地转换树以使结果代表这个有序序列?
F<G<H<A<B<C<D<E?
从 F 向右的元素被移动到所有其他元素的前面。请注意,这与通常意义上的“树旋转”无关。这里的旋转发生在元素顺序的意义上。这与双向链表的“旋转”的含义相同。例如,如果问题是关于双向链表而不是二叉搜索树,则解决方案很简单:
E.next := null
F.prev := null
H.next := A
A.prev := H
平衡二叉搜索树是否有有效的解决方案?
实施说明:
乍一看,即使有一个有效的算法,它也没有多大用处,因为必须更新移动元素的值以保留二叉搜索树的不变量(左孩子较小,右孩子更大)。但是,情况并非如此,因为在模算术模N中,顺序可以在恒定时间内固定,而无需更改节点的值。假设节点的顺序定义如下:
(A < B) if and only if ((A.value - C) mod N) < ((B.value - C) mod N)
这里,A.value、B.value和C是[0,N)范围内的整数。对此的图形解释是,我们有一个散布有N个点的圆,我们对这些点进行排序,使得C是最小的点,然后是C+1、C+2等,直到C+(N-1),这是最大的一点。
无论如何,在将F和所有后续元素移到前面之后,可以通过更改C轻松修复树不变量:
C := F.value