[英]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有两棵树,它们的顺序如下
/*
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.