给定两棵二叉树,我们必须检测这两棵树是否是同构的。如果两个树中的一个可以通过一系列翻转(即通过交换多个节点的左右子节点)从另一个中获得,则两棵树被称为同构。任何级别的任意数量的节点都可以交换它们的子节点。
注意:两棵空树是同构的。
例如,以下两棵树是同构的,其中翻转了以下子树:2 和 3,NULL 和 6、7 和 8。
方法:
为了解决上面提到的问题,我们使用层序遍历迭代遍历两棵树,并将层存储在队列数据结构中。每个级别有以下两个条件:
- 节点的值必须相同。
- 每个级别的节点数应该相同。
检查队列的大小以匹配上面提到的第二个条件。将第一棵树的每个级别的节点存储为带有值的键,对于第二棵树,我们将一个级别的所有节点存储在一个向量中。如果找到键,我们将减小该值以跟踪在某个级别存在多少具有相同值的节点。如果该值变为零,则意味着第一棵树只有这么多节点,我们将其作为键删除。在每个级别的末尾,我们将遍历数组并检查每个值是否存在于地图上。会有三个条件:
- 如果未找到键,则第一棵树不包含在同一级别的第二棵树中找到的节点。
- 如果找到键但值变为负数,则第二棵树有更多节点,其值与第一棵树相同。
- 如果地图大小不为零,这意味着还剩下一些键,这意味着第一棵树的节点与第二棵树中的任何节点都不匹配。
下面是上述方法的实现:
C++
// C++ program to find two
// Binary Tree are Isomorphic or not
#include
using namespace std;
/* A binary tree node has data,
pointer to left and right children */
struct node {
int data;
struct node* left;
struct node* right;
};
/* function to retun if
tree are isomorphic or not*/
bool isIsomorphic(node* root1, node* root2)
{
// if Both roots are null
// then tree is isomorphic
if (root1 == NULL and root2 == NULL)
return true;
// check if one node is false
else if (root1 == NULL or root2 == NULL)
return false;
queue q1, q2;
// enqueue roots
q1.push(root1);
q2.push(root2);
int level = 0;
int size;
vector v2;
unordered_map mp;
while (!q1.empty() and !q2.empty()) {
// check if no. of nodes are
// not same at a given level
if (q1.size() != q2.size())
return false;
size = q1.size();
level++;
v2.clear();
mp.clear();
while (size--) {
node* temp1 = q1.front();
node* temp2 = q2.front();
// dequeue the nodes
q1.pop();
q2.pop();
// check if value
// exists in the map
if (mp.find(temp1->data) == mp.end())
mp[temp1->data] = 1;
else
mp[temp1->data]++;
v2.push_back(temp2->data);
// enqueue the child nodes
if (temp1->left)
q1.push(temp1->left);
if (temp1->right)
q1.push(temp1->right);
if (temp2->left)
q2.push(temp2->left);
if (temp2->right)
q2.push(temp2->right);
}
// Iterate through each node at a level
// to check whether it exists or not.
for (auto i : v2) {
if (mp.find(i) == mp.end())
return false;
else {
mp[i]--;
if (mp[i] < 0)
return false;
else if (mp[i] == 0)
mp.erase(i);
}
}
// check if the key remain
if (mp.size() != 0)
return false;
}
return true;
}
/* function that allocates a new node with the
given data and NULL left and right pointers. */
node* newnode(int data)
{
node* temp = new node;
temp->data = data;
temp->left = NULL;
temp->right = NULL;
return (temp);
}
/* Driver program*/
int main()
{
// create tree
struct node* n1 = newnode(1);
n1->left = newnode(2);
n1->right = newnode(3);
n1->left->left = newnode(4);
n1->left->right = newnode(5);
n1->right->left = newnode(6);
n1->left->right->left = newnode(7);
n1->left->right->right = newnode(8);
struct node* n2 = newnode(1);
n2->left = newnode(3);
n2->right = newnode(2);
n2->right->left = newnode(4);
n2->right->right = newnode(5);
n2->left->right = newnode(6);
n2->right->right->left = newnode(8);
n2->right->right->right = newnode(7);
if (isIsomorphic(n1, n2) == true)
cout << "Yes";
else
cout << "No";
return 0;
}
Java
// Java program to find two
// Binary Tree are Isomorphic or not
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Queue;
class GFG{
// A binary tree node has data,
// pointer to left and right children
static class Node
{
int data;
Node left, right;
public Node(int data)
{
this.data = data;
this.left = this.right = null;
}
};
// Function to retun if tree
// are isomorphic or not
static boolean isIsomorphic(Node root1,
Node root2)
{
// If Both roots are null
// then tree is isomorphic
if (root1 == null &&
root2 == null)
return true;
// Check if one node
// is false
else if (root1 == null ||
root2 == null)
return false;
Queue q1 =
new LinkedList<>(),
q2 = new LinkedList<>();
// Enqueue roots
q1.add(root1);
q2.add(root2);
int level = 0;
int size;
ArrayList v2 =
new ArrayList<>();
HashMap mp = new HashMap<>();
while (!q1.isEmpty() &&
!q2.isEmpty())
{
// check if no. of nodes are
// not same at a given level
if (q1.size() != q2.size())
return false;
size = q1.size();
level++;
v2.clear();
mp.clear();
while (size-- > 0)
{
// Dequeue the nodes
Node temp1 = q1.poll();
Node temp2 = q2.poll();
// Check if value
// exists in the map
if (!mp.containsKey(temp1.data))
mp.put(temp1.data, 1);
else
mp.put(temp1.data,
mp.get(temp1.data) + 1);
v2.add(temp2.data);
// Enqueue the child nodes
if (temp1.left != null)
q1.add(temp1.left);
if (temp1.right != null)
q1.add(temp1.right);
if (temp2.left != null)
q2.add(temp2.left);
if (temp2.right != null)
q2.add(temp2.right);
}
// Iterate through each node
// at a level to check whether
// it exists or not.
for (Integer i : v2)
{
if (!mp.containsKey(i))
return false;
else
{
mp.put(i, mp.get(i) - 1);
if (mp.get(i) < 0)
return false;
else if (mp.get(i) == 0)
mp.remove(i);
}
}
// Check if the key remain
if (mp.size() != 0)
return false;
}
return true;
}
// Driver program
public static void main(String[] args)
{
// Create tree
Node n1 = new Node(1);
n1.left = new Node(2);
n1.right = new Node(3);
n1.left.left = new Node(4);
n1.left.right = new Node(5);
n1.right.left = new Node(6);
n1.left.right.left = new Node(7);
n1.left.right.right = new Node(8);
Node n2 = new Node(1);
n2.left = new Node(3);
n2.right = new Node(2);
n2.right.left = new Node(4);
n2.right.right = new Node(5);
n2.left.right = new Node(6);
n2.right.right.left = new Node(8);
n2.right.right.right = new Node(7);
if (isIsomorphic(n1, n2))
System.out.println("Yes");
else
System.out.println("No");
}
}
// This code is contributed by sanjeev2552
Python3
# Python3 program to find two
# Binary Tree are Isomorphic or not
from collections import deque
class node:
def __init__(self, x):
self.data = x
self.left = None
self.right = None
# Function to retun if tree are
# isomorphic or not
def isIsomorphic(root1, root2):
# If Both roots are null
# then tree is isomorphic
if (root1 == None and root2 == None):
return True
# Check if one node is false
elif (root1 == None or root2 == None):
return False
q1 = deque()
q2 = deque()
# enqueue roots
q1.append(root1)
q2.append(root2)
level = 0
size = 0
v1 = []
m2 = {}
while (len(q1) > 0 and len(q2) > 0):
# Check if no. of nodes are
# not same at a given level
if (len(q1) != len(q2)):
return False
size = len(q1)
level += 1
v2 = []
mp = {}
while (size):
temp1 = q1.popleft()
temp2 = q2.popleft()
# Check if value
# exists in the map
mp[temp1.data] = mp.get(temp1.data, 0) + 1
v2.append(temp2.data)
# enqueue the child nodes
if (temp1.left):
q1.append(temp1.left)
if (temp1.right):
q1.append(temp1.right)
if (temp2.left):
q2.append(temp2.left)
if (temp2.right):
q2.append(temp2.right)
v1 = v2
m2 = mp
size -= 1
# Iterate through each node at a level
# to check whether it exists or not.
for i in v1:
if i in m2:
return True
else:
m2[i] -= 1
if (m2[i] < 0):
return False
elif (m2[i] == 0):
del m2[i]
# Check if the key remain
if (len(m2) == 0):
return False
return True
# Driver code
if __name__ == '__main__':
# Create tree
n1 = node(1)
n1.left = node(2)
n1.right = node(3)
n1.left.left = node(4)
n1.left.right = node(5)
n1.right.left = node(6)
n1.left.right.left = node(7)
n1.left.right.right = node(8)
n2 = node(1)
n2.left = node(3)
n2.right = node(2)
n2.right.left = node(4)
n2.right.right = node(5)
n2.left.right = node(6)
n2.right.right.left = node(8)
n2.right.right.right = node(7)
if (isIsomorphic(n1, n2) == True):
print("Yes")
else:
print("No")
# This code is contributed by mohit kumar 29
C#
// C# program to find two
// Binary Tree are Isomorphic or not
using System;
using System.Collections;
using System.Collections.Generic;
class GFG{
// A binary tree node has data,
// pointer to left and right children
class Node
{
public int data;
public Node left, right;
public Node(int data)
{
this.data = data;
this.left = this.right = null;
}
};
// Function to retun if tree
// are isomorphic or not
static bool isIsomorphic(Node root1,
Node root2)
{
// If Both roots are null
// then tree is isomorphic
if (root1 == null &&
root2 == null)
return true;
// Check if one node
// is false
else if (root1 == null ||
root2 == null)
return false;
Queue q1 = new Queue();
Queue q2 = new Queue();
// roots
q1.Enqueue(root1);
q2.Enqueue(root2);
int level = 0;
int size;
ArrayList v2 = new ArrayList();
Dictionary mp = new Dictionary();
while (q1.Count != 0 && q2.Count != 0)
{
// check if no. of nodes are
// not same at a given level
if (q1.Count != q2.Count)
return false;
size = q1.Count;
level++;
v2.Clear();
mp.Clear();
while (size-- > 0)
{
// Dequeue the nodes
Node temp1 = (Node)q1.Dequeue();
Node temp2 = (Node)q2.Dequeue();
// Check if value
// exists in the map
if (!mp.ContainsKey(temp1.data))
mp[temp1.data] = 1;
else
mp[temp1.data]++;
v2.Add(temp2.data);
// the child nodes
if (temp1.left != null)
q1.Enqueue(temp1.left);
if (temp1.right != null)
q1.Enqueue(temp1.right);
if (temp2.left != null)
q2.Enqueue(temp2.left);
if (temp2.right != null)
q2.Enqueue(temp2.right);
}
// Iterate through each node
// at a level to check whether
// it exists or not.
foreach (int i in v2)
{
if (!mp.ContainsKey(i))
return false;
else
{
mp[i]--;
if (mp[i] < 0)
return false;
else if (mp[i] == 0)
mp.Remove(i);
}
}
// Check if the key remain
if (mp.Count != 0)
return false;
}
return true;
}
// Driver program
public static void Main(string[] args)
{
// Create tree
Node n1 = new Node(1);
n1.left = new Node(2);
n1.right = new Node(3);
n1.left.left = new Node(4);
n1.left.right = new Node(5);
n1.right.left = new Node(6);
n1.left.right.left = new Node(7);
n1.left.right.right = new Node(8);
Node n2 = new Node(1);
n2.left = new Node(3);
n2.right = new Node(2);
n2.right.left = new Node(4);
n2.right.right = new Node(5);
n2.left.right = new Node(6);
n2.right.right.left = new Node(8);
n2.right.right.right = new Node(7);
if (isIsomorphic(n1, n2))
Console.WriteLine("Yes");
else
Console.WriteLine("No");
}
}
// This code is contributed by rutvik_56
输出:
Yes
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live