伪代码比较两棵树

时间:2013-10-11 05:12:49

标签: algorithm tree pseudocode

这是我遇到过几次的问题,并且我们并没有确信我使用过最有效的逻辑。

举个例子,假设我有两棵树:一个是文件夹结构,另一个是内存中的模型'该文件夹结构。我希望比较两棵树,并生成一个树中存在的节点列表而不是另一棵树 - 反之亦然。

是否有可接受的算法来处理此问题?

5 个答案:

答案 0 :(得分:10)

看起来好像你只想进行预订遍历。 “访问”节点意味着检查一个版本而不是另一个版本的子项。

更准确地说:从根开始。在每个节点上,在节点的两个版本中的每个版本中获取一组项目。两组的对称差异包含一个而不是另一个的项目。打印/输出那些。交集包含两者共有的项目。对于交集中的每个项目(我假设您不打算进一步查看一棵树中缺少的项目),在该节点上递归调用“visit”以检查其内容。这是一个O(n)操作,带有一点递归开销。

答案 1 :(得分:3)

public boolean compareTrees(TreeNode root1, TreeNode root2) {
  if ((root1 == null && root2 != null) || 
      (root1 != null && root2 == null)) {
    return false;
  }

  if (root1 == null && root2 == null) {
    return true;
  }

  if (root1.data != root2.data) {
    return false;
  }

  return compareTrees(root1.left, root2.left) && 
    compareTrees(root1.right, root2.right);
}

答案 2 :(得分:1)

如果使用排序树(如AVL树),还可以按顺序有效地遍历树。这将按照从“低”到“高”的排序顺序返回您的路径。 然后,您可以使用与树算法中使用的相同的比较方法对目录数组(例如,使用快速排序)进行排序。

然后开始并排比较两个,通过按顺序遍历树并检查已排序目录数组中的下一个项目,前进到下一个项目。

这在实践中应该更有效,但只有基准测试可以说明。

答案 3 :(得分:1)

您可能还想看看git的工作方式。基本上,每当您执行git diff时,就在树下进行了树比较。

答案 4 :(得分:0)

python中的一个简单示例代码。

class Node(object):
  def __init__(self, val):
    self.val = val
    self.child = {}

  def get_left(self):
    #if left is not in the child dictionary that means the element does not have a left child
    if 'left' in self.child:
      return self.child['left']
    else:
      return None

  def get_right(self):
    #if right is not in the child dictionary that means the element does not have a rigth child
    if 'right' in self.child:
      return self.child['right']
    else:
      return None


def traverse_tree(a):
  if a is not None:
    print 'current_node : %s' % a.val
    if 'left' in a.child:
      traverse_tree(a.child['left'])

    if 'right' in a.child:
      traverse_tree(a.child['right'])



def compare_tree(a, b):
  if (a is not None and b is None) or (a is None and b is not None):
    return 0
  elif a is not None and b is not None:
    print a.val, b.val
    #print 'currently comparing a : %s, b : %s, left : %s, %s , right : %s, %s' % (a.val, b.val, a.child['left'].val, b.child['left'].val, a.child['right'].val, b.child['right'].val)
    if a.val==b.val and compare_tree(a.get_left(), b.get_left()) and compare_tree(a.get_right(), b.get_right()):
      return 1
    else:
      return 0
  else:
    return 1

#Example
a = Node(1)
b = Node(0)
a.child['left'] = Node(2)
a.child['right'] = Node(3)
a.child['left'].child['left'] = Node(4)
a.child['left'].child['right'] = Node(5)
a.child['right'].child['left'] = Node(6)
a.child['right'].child['right'] = Node(7)
b.child['left'] = Node(2)
b.child['right'] = Node(3)
b.child['left'].child['left'] = Node(4)
#b.child['left'].child['right'] = Node(5)
b.child['right'].child['left'] = Node(6)
b.child['right'].child['right'] = Node(7)
if compare_tree(a, b):
  print 'trees are equal'
else:
  print 'trees are unequal'
#DFS traversal
traverse_tree(a)

还粘贴了一个可以运行的示例。