从二叉树中删除重复项

时间:2013-11-16 01:11:46

标签: algorithm language-agnostic tree binary-tree

我试图想出一种从二叉树/二叉搜索树中删除重复项的算法。到目前为止,我能想到的最好的是

  

在数组中存储树的遍历遍历。
  如果树没有排序,则对数组进行排序   从数组中删除重复项并重新构建二叉树。

我们是否还需要存储树的预订序遍历以重建树?

这会将复杂性置于O(n log n )时间和O(n)空间。我们可以做得更好吗?伪代码/代码样本将不胜感激

编辑1:假设二叉树的结构由以下对象

给出
public class Node
{
   int data;
   Node right;
   Node left;
// getters and setters for the left and right nodes
}

5 个答案:

答案 0 :(得分:2)

删除二进制搜索树的重复算法:

  1. 开始树步行(在/前/后订购)

  2. 在每个节点上,对以该节点为根的子树进行二进制搜索,以获取存储在节点中的键值。

    如果在树下找到键值,请调用delete(键)并重新启动步骤2(可能有多个重复项)。

    重复步骤2,直到在子树中找不到密钥。然后返回步骤1

  3. 时间复杂度 - O(nlogn)(对于每个n元素执行二元搜索,需要logn

    空间复杂度 - O(logn)(用于递归中使用的堆栈空间)

答案 1 :(得分:0)

我有一个奇怪的想法:

如果您已经有一个重复的树,并且需要构建一个没有重复的新树,那么您可以:

  1. 创建节点值的空哈希值
  2. 创建新树
  3. 以任何顺序遍历现有树并逐个获取元素
  4. 如果元素已存在于哈希映射中,则不要将其添加到新的 树
  5. 可以吗?)

答案 2 :(得分:0)

为您的问题提出递归解决方案: -

deleteDup(Node p) {

  if(p == NULL) return

  else {

    deleteDup(p.left)
    deleteDup(p.right)
    delete(p.value,p.left)
    delete(p.value,p.right)

  } 

 }

 deleteDup(root)

时间复杂度:

BST删除= O(logN)

T(N) = 2T(N/2) + O(logN)
T(N) = O(N)

空间复杂性:O(logN)

注意: - 假设BST平衡

答案 3 :(得分:0)

我有另一个想法,在O(n)时间和O(n)空间运行。 例如,我们有一棵树有根A和两个孩子A和B.  一个 A B

  1. 创建一个Map计数,将树中的每个值映射到一个计数。
  2. 遍历树中的所有元素以填充计数。我们将得到计数[A] = 2并且计数[B] = 1。这需要O(n)空间和O(n)时间。
  3. 再次,遍历树中的所有元素。对于每个元素,检查count [element]> 1如果是这样,我们设置count [element] - ,并删除该元素(使用二叉树删除/旋转)。这是O(n)时间。
  4. 一旦完成,树就没有重复了!

答案 4 :(得分:-1)

这种情况下的诀窍是不要将重复项存储起来......

当您将节点添加到树中时,为什么不能在树中已经存在重复的情况下决定不添加节点?