简体   繁体   English

检查两个二叉搜索树是否具有相同的中序遍历

[英]Check two binary search trees have the same in-order traversal

Check two binary search trees have the same in-order traversal.检查两个二叉搜索树是否具有相同的中序遍历。 My naive approach is to in-order traverse the given two trees and copy each element onto an array separately, then check these two arrays are the same.我天真的方法是按顺序遍历给定的两棵树,并将每个元素分别复制到一个数组中,然后检查这两个数组是否相同。 But I feel like we should be able to just copy elements from one tree onto an array and use that array to verify the other tree on the fly, instead of using two arrays.但是我觉得我们应该能够将一棵树中的元素复制到一个数组中,然后使用该数组来动态验证另一棵树,而不是使用两个数组。 Or better yet, there may be a way to do it without using any array.或者更好的是,可能有一种方法可以在不使用任何数组的情况下做到这一点。 My code is following, not sure if my implementation of hasSameInOrder() is correct.我的代码如下,不确定我对 hasSameInOrder() 的实现是否正确。 Or could we do it without using any array?或者我们可以在不使用任何数组的情况下做到这一点吗? Please note that two trees having the same in-order traversal mean if you copy the elements onto an array when in-order traversing, the two resulted array should have the same value.请注意,具有相同中序遍历的两棵树意味着如果在中序遍历时将元素复制到数组中,则两个结果数组应具有相同的值。 So they don't necessarily have the same structure in order to have the same in-order traversal.因此,它们不一定具有相同的结构以具有相同的有序遍历。

public boolean checkTwoBSTHaveSameInOrder(Node n1, Node n2) {
   LinkedList<Node> queue = new LinkedList<Node>();
   inOrder(n1, buffer);
   hasSameInOrder(n2, queue)
   return queue==null? false: true;
}
public void inOrder(Node node, LinkedList<Node> queue) {
   if (node==null)
       return;
   inOrder(node.left, queue);
   queue.add(node);
   inOrder(node.right, queue);
}
public void hasSameInOrder(Node node, LinkedList<Node> queue) {
   if (node==null)
      return;
   hasSameInOrder(n2.left, queue));
   if (queue==null)
      return;
   else {
      if (node!=queue.poll())
           queue=null;
   }
   hasSameInOrder(n2.right, queue));
} 

Use a single loop in the iterative implementation of the Inorder Traversal for both trees.You will need two added stacks(read queue) to keep track of the match.在两个树的中序遍历的迭代实现中使用单个循环。您将需要添加两个堆栈(读取队列)来跟踪匹配。 Obviously this is not going to improve the worst case asymptotic time which is impossible to better, but the on hand approach ensures a reasonable time gain on a random pair of trees.显然,这不会改善不可能更好的最坏情况渐近时间,但现有方法确保在随机一对树上获得合理的时间增益。

You can use a single array in following manner :-您可以按以下方式使用单个数组:-

int count =0;
int[] arr;

void inorder(node*p) {

  if(p!=null) {

       inorder(p->left);
       arr[count++] = p->data;
       inorder(p->right);
  }  

}

int c2 =0;
boolean checkSame(node*p,int[] arr) {

    if(p!=null) {
       boolean t = true;  
       t = checkSame(p->left,arr);
       if(c2+1>=count||arr[c2++]!=p->data) {

           return(false);  
       } 
       return(t&&checkSame(p->right,arr));

    }

}

If we can restructure the tree, then transfer both the trees to left or right skewed format, then do the comparison in a single traversal Skewed Tree如果我们可以重构树,那么将两棵树都转换为左偏或右偏的格式,然后在单个遍历偏斜树中进行比较

Else we can avoid the cost by transferring only one tree to the skewed format and compare it while doing inorder traversal of other.否则,我们可以通过仅将一棵树转换为倾斜格式并在对其他树进行中序遍历的同时进行比较来避免成本。

Yes, there is a way to do it without using array.是的,有一种方法可以在不使用数组的情况下做到这一点。 We can achieve it using Threads.我们可以使用线程来实现它。 We can interact among threads using wait() and notify().我们可以使用wait() 和notify() 在线程之间进行交互。 Trigger recursive inorder traversal in both trees in separate threads.在不同线程中的两棵树中触发递归中序遍历。 Read first element in one tree and wait for other tree to read its first element.读取一棵树中的第一个元素并等待另一棵树读取其第一个元素。 Compare these elements and proceed to remaining elements.比较这些元素并继续处理剩余的元素。 You can follow below sample code.您可以按照以下示例代码进行操作。

//common lock for both threads
Object lock = new Object();

// flag to check if traverseFirstTree can come out of wait or not
boolean proceedFirst = false;

// flag to check if traverseSecondTree can come out of wait or not
boolean proceedSecond = false;

//value of current element in second BinarySearchTree
int element;

boolean identicalInorderOrNot(BST bst1, BST bst2){
  //check if no. of elements in both are same. If not return false
  if (bst1.size() != bst2.size()){
    return false;
  } 
  Thread thread = new Thread (new Runnable(){
    void run(){
      traverseSecondTree(bst2);
    }
  });
  //it does not matter if traverseSecondTree gets executed before traverseFirstTree(), as we have check for this condition
  thread.start()
  return traverseFirstTree(bst1);
}

private boolean traverseFirstTree(BST node){
  if(bst1 == null){
    return true;
  }
  if (!traverseFirstTree(node.left)){
    return false;
  }
  synchronized(lock){
    proceedFirst = false;
    while (!proceedFirst){
      proceedSecond = true;
      wait();
    }
  notify()
  }
  //check if root data of bst1 is same as current element of bst2
  if (node.data != element){
    return false;
  }
  return traverseFirstTree(node.right)
}

private void traverseSecondTree(BST node){
  if (node ==  null){
    return true;
  }
  traverseSecondTree(node.left)
  synchronized(lock){
    while (!proceedSecond){
      wait();
    }
    element = node.data;
    proceedFirst = true;
    proceedSecond = false;
    notify();

  traverseSecondTree(node.right)
}

We can do it in more better space complexity O(1) We can use Morris Traversal to iterate over the trees and compare the values element by element.我们可以在更好的空间复杂度 O(1) 中做到这一点我们可以使用 Morris Traversal 遍历树并逐个元素比较值。

I am assuming both tree have same number of nodes for the below implementation.对于下面的实现,我假设两棵树都有相同数量的节点。

  bool isSame(root1, root2){
    while(root1!=null && root2!=null){
        while(root1->left!=NULL){
            auto maxleft = getmaxnode(root1->left);
            maxleft->right = root1;
            auto next = root1->left;
            root1->left = NULL;
            root1 = next;
        }
        while(root2->left!=NULL){
            auto maxleft = getmaxnode(root2->left);
            maxleft->right = root2;
            auto next = root2->left;
            root2->left = NULL;
            root2 = next;
        }
        if(root1->val != root2->val) return false;
    }
    return true;
}

There are two tree which in order are same as follow有两棵树,它们的顺序如下

  1. InOrder function tree1 will populate queue InOrder 函数 tree1 将填充队列
  2. CheckInOrder function will compare the value with second tree CheckInOrder 函数会将值与第二棵树进行比较
  3. if there is a mismatch return false如果不匹配返回 false
    /*
      Tree 1           Tree 2
         5                3
        / \              / \
       3   7            1   6
      /   /                / \
     1   6                5   7
    [1,3,5,6,7]      [1,3,5,6,7]
    */
    
    #include <iostream>
    #include <queue>
    
    using namespace std;
    
    struct NODE {
        NODE() {
            val = 0;
            left = NULL;
            right = NULL;
        }
    
        NODE(int n) {
            val = n;
            left = NULL;
            right = NULL;
        }
        int val;
        NODE* left;
        NODE* right;
    };
    
    void InOrder(NODE* root, queue<int>& q)
    {
        if (root == NULL)
            return;

        InOrder(root->left, q);
        q.push(root->val);
        InOrder(root->right, q);
    }
        
    bool CheckInOrder(NODE* root, queue<int>& q)
    {
        if (root == NULL)
            return true;
        if (!CheckInOrder(root->left, q))
            return false;
        if (!q.empty() && root->val == q.front())
            q.pop();
        else
            return false;
    
        return CheckInOrder(root->right, q);
    }
    
    int main()
    {
        NODE* tree1;
        NODE* tree2;
        queue<int> tq;
    
        tree1 = new NODE(5);
        tree1->left = new NODE(3);
        tree1->right = new NODE(7);
        tree1->left->left = new NODE(1);
        tree1->right->left = new NODE(6);
    
        tree2 = new NODE(3);
        tree2->left = new NODE(1);
        tree2->right = new NODE(6);
        tree2->right->left = new NODE(5);
        tree2->right->right = new NODE(7);
    
        InOrder(tree1, tq);
        if (CheckInOrder(tree2, tq) && tq.empty())
            cout << "TRUE";
        else
            cout << "FALSE";
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用递归检查 2 个 BST 是否同时具有相同的中序遍历 - Check if 2 BSTs have the same in-order traversal simultaneously using recursion 将有序遍历元素发送到数组 - Sending in-order traversal elements to array 如何检查给定的数组是否表示二进制搜索树的后遍历? - How to check if a given array represents postorder traversal of Binary Search Tree? 检查两个数组是否具有相同顺序的元素 - Check whether two arrays have same elements in some order 检查两个数组是否具有相同的内容(按任何顺序) - Check if two arrays have the same contents (in any order) 尝试返回二叉树的级别顺序遍历 - Trying to return a level order traversal of a binary tree java-如何检查两个序列是否以某种顺序具有相同的值,(忽略重复项) - How to check whether two sequences have the same values in some order, (ignoring duplicates) java 我想将左平衡二叉树的数组表示形式从按顺序转换为级别顺序表示形式: - I want to convert an array represeantation of left balanced binary tree from In-order to Level order representation: 检查json中的两个数组大小是否相同 - Check that two arrays in json have the same size 有没有办法检查两个数组是否具有相同的元素? - Is there a way to check if two arrays have the same elements?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM