在二叉搜索树中查找重复条目的策略

时间:2011-10-09 23:39:46

标签: java algorithm binary-tree

我有一个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));

这意味着重复项将被添加到重复项的右侧..对吗?

4 个答案:

答案 0 :(得分:2)

你展示的树假设(好吧,至少我假设...... ;-))小于左边,大于右边,我是对的吗?

所以你应该考虑两件事:

  1. 你的树错了! “10”头右侧的第二个“8”不能存在,因为它小于10.正确的插入和正确的平衡,如果不是在“下一次”迭代中,它们都会非常接近来自“左8”。

  2. 通过在左侧将树定义为“小于或等于”,在右侧定义“大于或大”,您将得到想要的结果:所有“8”将被链接到在简单的插入树上彼此左侧。

答案 1 :(得分:2)

  1. 使用通常的二叉树搜索算法查找与您的密钥匹配的元素。如果没有找到,请停止。
  2. 检查LH子分支。如果其键匹配,则将其设为当前节点并重复此步骤。
  3. 您现在位于树中具有该键的第一个元素。现在,当密钥相等时,从该节点进行树步行,即访问此节点,右子树,父节点,父节点的右子树等,作为读者的练习。

答案 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[] {});
}
相关问题