我有一个BST,它有重复的条目。我想找到重复的条目。现在显然我可以编写一个遍历整个树的哑算法,这很容易。
但是,我想写一个更高效的。这就是我到目前为止所做的一切:
假设以下树。
10
/ \
5 15
/\ / \
2 8 10 16
\ \
8 12
如果我想找到所有8个,我将首先找到10个左侧子树上的8个。要找到重复项,如果它没有正确的子项,它是否会是右侧最左边的节点 - 比该节点(8)大的第一个父节点的子节点?如果它确实有一个正确的子节点,那么它可以位于其右子树的最左侧节点或左侧子树的最右侧节点上?
那些是所有情况,可以通过一堆循环和if语句来实现吗?
如果没有,有什么更好的方法?有人可以帮忙吗?
由于
编辑: 实际上我刚刚意识到它不能是“最左边的节点”或“最右边的节点”。这将找到下一个最高值或前一个最低值的节点。它之前会是一个节点吗?
编辑2:
修正了我的BST示例。它遵循以下插入方法:
if (node == null)
return new NodeBST<Value>(name, value);
if (node.key().compareTo(name) > 0)
node.setLeft(insert(node.left(), name, value));
else
node.setRight(insert(node.right(), name, value));
这意味着重复项将被添加到重复项的右侧..对吗?
答案 0 :(得分:2)
你展示的树假设(好吧,至少我假设...... ;-))小于左边,大于右边,我是对的吗?
所以你应该考虑两件事:
你的树错了! “10”头右侧的第二个“8”不能存在,因为它小于10.正确的插入和正确的平衡,如果不是在“下一次”迭代中,它们都会非常接近来自“左8”。
通过在左侧将树定义为“小于或等于”,在右侧定义“大于或大”,您将得到想要的结果:所有“8”将被链接到在简单的插入树上彼此左侧。
答案 1 :(得分:2)
答案 2 :(得分:0)
递归算法可以快速解决这个问题。您不必递归整个树,因为您可以使用BST的结构来搜索所需的值。
你所画的并不是严格意义上的BST,我可能错了,但我相信它很糟糕 - 左边树中的所有数字都应该小于10,反之亦然。
答案 3 :(得分:0)
此实现使用递归方法并返回重复条目数组
public class TreeNode<E> {
public int data;
public TreeNode left;
public TreeNode right;
}
public Integer[] findDuplicate(TreeNode tree) {
Map<Integer, Integer> entries = new HashMap<>();
List<Integer> duplicates = new LinkedList<>();
return (Integer[]) findDuplicate(tree, entries, duplicates);
}
private Integer[] findDuplicate(TreeNode tree, Map entries, List duplicates) {
if (tree == null)
return (Integer[]) duplicates.toArray(new Integer[] {});
if (entries.containsKey(tree.data))
duplicates.add(tree.data);
else
entries.put((int) tree.data, 1);
findDuplicate(tree.left, entries, duplicates);
findDuplicate(tree.right, entries, duplicates);
return (Integer[]) duplicates.toArray(new Integer[] {});
}