我想在二元搜索树中找到一个节点 - v,它满足以下条件中的一个(且只有一个):
我知道我的树中只存在一个节点v - T,我想找到它。
我想到了这个算法,给出了一个树T:
所以我的第一个问题是:算法是否正确?它做了它的假设吗?
其次,我需要及时复杂O(n)
这种情况发生了吗?
如果我错了,我很乐意为这个问题找到一个有效的算法
答案 0 :(得分:2)
您可以通过将条件转换为代码来完全实现算法:
boolean hasValueSmallerThan(Vertex startFrom, int value) {
return
this.value < value
|| (startFrom.left != null && hasValueSmallerThan(startFrom.left, value))
|| (startFrom.right != null && hasValueSmallerThan(startFrom.right, value));
}
boolean hasValueGreaterThan(Vertex startFrom, int value) {
return
this.value > value
|| (startFrom.left != null && hasValueGreaterThan(startFrom.left, value))
|| (startFrom.right != null && hasValueGreaterThan(startFrom.right, value));
}
Vertex findInvalid(Vertex startFrom) {
if (startFrom.left == null && startFrom.right == null) {
return null;
}
// v's right subtree includes at least one value that is bigger than v
if (startFrom.left == null) {
boolean checkRight = hasValueGreaterThan(startFrom.right, this.value);
return (checkRight) ? this : findInvalid(startFrom.right);
}
// v's left subtree includes at least one value that is smaller than v
if (startFrom.right == null) {
boolean checkLeft = hasValueSmallerThan(startFrom.left, this.value);
return (checkLeft) ? this : findInvalid(startFrom.left);
}
// If we are here, both subrtees are non-null
boolean leftIsInvalid = hasValueSmallerThan(startFrom.left, this.value);
boolean rightIsInvalid = hasValueGreaterThan(startFrom.right, this.value);
// Return XOR of the two checks, which means "one of the two is true, but not both"
if (leftIsInvalid ^ rightIsInvalid) {
return this;
}
Vertex leftFind = findInvalid(startFrom.left);
if (leftFind != null) return leftFind;
return findInvalid(startFrom.right);
}
这个实现非常简单:它有两个递归助手hasValueSmallerThan
和hasValueGreaterThan
,它们由递归findInvalid
使用。
当大多数代码处理两个子树中的一个为空时的情况。除此之外,它可以直接将需求转换为代码。
答案 1 :(得分:1)
你的算法没有按照预期的那样做。考虑以下树:
3
/ \
2 5
/ \
1 4
没有节点有一个违反排序的子节点,但根的左子树包含的值大于根。