我有一个数据结构作业,除了常规的AVL树函数之外,我还要添加一个函数,它返回AVL树中任意两个数字之间的最小间隙(AVL中的节点实际上代表数字。)
假设我们在AVL树中有数字(作为节点)1 5 12 20 23 21,该函数应该返回任意两个数字之间的最小间隙。在这种情况下它应该返回“1”,即| 20-21 |或| 21-20 |。
应该在O(1)中完成。
试图思考很多,我知道有一个伎俩但是找不到它,我花了好几个小时。
还有另一项任务是找到最大间隙,这很容易,它是最小和最大数之间的差异。
答案 0 :(得分:6)
您需要扩展数据结构,否则您无法获得组成树的数字之间的最小间隙的O(1)搜索。
你有额外的约束,不会增加插入/删除/搜索功能的时间复杂度,我认为你也不想增加空间复杂性。
考虑一个通用节点 r ,左子树 r.L 和右子树 r.R ;我们将扩展节点 r 附加数字 r.x 中的信息,定义为:
之间的最小值(如果以前的条件都没有,则为未定义,如果是叶节点)
此外,为了快速插入/删除,我们需要在每个内部节点中添加对其最左侧和最右侧叶节点的引用。
您可以通过以下添加内容看到:
树中的最小间隙是根节点的 x 值,更具体地说,对于每个子树,子树元素中的最小间隙只是子树根 x 价值。
此声明的证明可以通过递归来完成: 让我们考虑一个以节点 r 为根的树,左子树 r.L 和右子树 r.R 。 归纳假设是 r.L 和 r.R x 值的根是子树的节点值之间的最小间隙的值。 很明显,只考虑值排序列表中具有相邻值的节点对,可以找到最小间隙;由 rL 节点存储的值形成的对在 rL 根 x 值中具有最小间隙,考虑到右边也是如此子树。鉴于( r.L 中的任何节点值)< L 根节点的值< ( r.R 中的任何节点值),唯一不考虑的相邻值对是两个:
具有较高值的 r.L 节点是AVL树属性的最右边的叶子,具有较低值的 r.R 节点是其最左边的叶子。 分配给 rx 值时,四个值之间的最小值(rL根x值,rR根x值,(r -rL根)间隙,(r -rR根)间隙)与分配相同整个树中连续节点值之间的较小间隙,相当于任何可能的节点值对之间的较小间隙。 子树中的一个或两个为空的情况是微不足道的。 只有一个或三个节点组成的树的基本情况,看到树根的x值是最小间隙值是微不足道的。
答案 1 :(得分:0)
此功能可能对您有所帮助:
int getMinGap(Node N)
{
int a = Integer.MAX_VALUE ,b = Integer.MAX_VALUE,c = Integer.MAX_VALUE,d = Integer.MAX_VALUE;
if(N.left != null) {
a = N.left.minGap;
c = N.key - N.left.max;
}
if(N.right != null) {
b = N.right.minGap;
d = N.right.min - N.key;
}
int minGap = min(a,min(b,min(c,d)));
return minGap;
}
这是节点数据结构:
class Node
{
int key, height, num, sum, min, max, minGap;
Node left, right;
Node(int d)
{
key = d;
height = 1;
num = 1;
sum = d;
min = d;
max = d;
minGap = Integer.MAX_VALUE;
}
}