Pseudocode to compare two trees

后端 未结 5 1978
猫巷女王i
猫巷女王i 2021-02-02 11:11

This is a problem I\'ve encountered a few times, and haven\'t been convinced that I\'ve used the most efficient logic.

As an example, presume I have two trees: one is a

相关标签:
5条回答
  • 2021-02-02 11:39

    You may also want to have a look at how git does it. Essentially whenever you do a git diff, under the hood a tree comparison is done.

    0 讨论(0)
  • 2021-02-02 11:46

    A simple example code in 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)
    

    Also pasted an example that you can run.

    0 讨论(0)
  • 2021-02-02 11:49

    If you use a sort tree, like an AVL tree, you can also traverse your tree efficiently in-order. That will return your paths in sorted order from "low" to "high". Then you can sort your directory array (e.g. Using quicksort) using the same compare method as you use in your tree algorithm.

    Then start comparing the two side by side, advancing to the next item by traversing your tree in-order and checking the next item in your sorted directory array.

    This should be more efficient in practice, but only benchmarking can tell.

    0 讨论(0)
  • 2021-02-02 11:58
    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);
    }
    
    0 讨论(0)
  • 2021-02-02 12:04

    Seems like you just want to do a pre-order traversal, essentially. Where "visiting" a node means checking for children that are in one version but not the other.

    More precisely: start at the root. At each node, get a set of items in each of the two versions of the node. The symmetric difference of the two sets contains the items in one but not the other. Print/output those. The intersection contains the items that are common to both. For each item in the intersection (I assume you aren't going to look further into the items that are missing from one tree), call "visit" recursively on that node to check its contents. It's a O(n) operation, with a little recursion overhead.

    0 讨论(0)
提交回复
热议问题