【问题标题】:Pseudocode to compare two trees比较两棵树的伪代码
【发布时间】:2013-10-19 02:14:05
【问题描述】:

这是我遇到过几次的问题,一直不相信我使用了最有效的逻辑。

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

是否有公认的算法来处理这个问题?

【问题讨论】:

  • 致对这个问题投了反对票的人。如果您能提供一些反馈意见,我将不胜感激,然后我可以获得更好的 Stack Overflow 参与者...

标签: algorithm tree pseudocode


【解决方案1】:

您可能还想看看git 是如何做到的。基本上每当您执行git diff 时,都会在后台进行树比较。

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

      【解决方案3】:

      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)
      

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

      【讨论】:

        【解决方案4】:
        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);
        }
        

        【讨论】:

          【解决方案5】:

          本质上,您似乎只想进行预订遍历。 “访问”一个节点意味着检查一个版本中的子节点,而不是另一个版本。

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

          【讨论】:

          • 注意:遍历是O(n)。对称差异和交集取决于您用于存储项目的容器,它们是否已排序等。
          猜你喜欢
          • 1970-01-01
          • 2017-05-02
          • 2021-01-14
          • 2021-10-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多