subject
Given two trees T1 and T2. If T1 can be changed into T2 through several child exchanges, we call the two trees isomorphic. For example, the two trees given in Fig. 1 are isomorphic, because when we exchange the left and right children of node A, B and G of one tree, we get another tree. Figure 2 is not isomorphic.
Figure 1
Figure 2
Given two trees, please judge whether they are isomorphic.
Input format:
Input gives information about two binary trees. For each tree, a non-negative integer N (< 10) is given in one line, i.e. the node number of the tree (assuming that the node is from 0 to N_1 number at this time); and then N lines, corresponding to the node number i, give a capital letter stored in the node, the number of the left child node and the number of the right child node. If the child's node is empty, give "-" in the corresponding position. The data given are separated by a space. Note: The Title ensures that the letters stored in each node are different.
Output format:
If the two trees are isomorphic, output "Yes" or "No".
Input Sample 1 (corresponding to Figure 1):
8 A 1 2 B 3 4 C 5 - D - - E 6 - G 7 - F - - H - - 8 G - 4 B 7 6 F - - A 5 1 H - - C 0 - D - - E 2 -
Output Sample 1:
Yes
Input Sample 2 (corresponding to Figure 2):
8 B 5 7 F - - A 0 3 C 6 - H - - D - - G 4 - E 1 - 8 D 6 - B 5 - E - - H - - C 0 2 G - 3 F - - A 1 4
Output Sample 2:
No
Requirement
Time limit: 400 ms Memory limit: 64 MB Code length limit: 16 KB
Interpretation of Subject Meaning
Given two trees T1 and T2. If T1 can be changed into T2 through several child exchanges, we call the two trees isomorphic. Given two trees, please judge whether they are isomorphic.
Input Format: Input gives information about two binary trees:
- The number of nodes of the tree is given in one line, followed by N lines.
- Line I corresponds to the number of node i, giving the letters stored in the node, the number of the left child node and the number of the right child node.
- If the child's node is empty, give "-" in the corresponding position.
### Input sample:
8 (First Tree)
A 1 2
B 3 4
C 5 -
D - -
E 6 -
G 7 -
F - -
H - -
=> Each row of input data corresponds to a node, numbered in turn
The corresponding binary tree is:
8 (Second Tree)
G - 4
B 7 6
F - -
A 5 1
H - -
C 0 -
D - -
E 2 -
=> Similarly, the number of each row of input data is in turn:
The corresponding binary tree is:
Thus, the root node is not required to be input as the first node.
Solution Thought
- Binary Tree Representation
- Building Binary Trees
- By discrimination
Binary Tree Representation
1) The most common representation (linked list):
2) Represented by an array (Completed into a complete binary tree):
3) Representing binary trees with structured arrays: static linked lists (physical storage is an array, ideological is the idea of linked lists)
Each column is a component of the array, which contains three messages: the letters stored in the node itself, and the subscripts of Left and Right pointing to the location of the left and right sons. Use - 1 to denote the node pointing to empty.
Data structure definition:
#define MaxTree 10 #define ElementType char #define Tree int #Define Null-1// In order to distinguish the keyword NULL(0), the custom representative is -1. struct TreeNode { ElementType Element; Tree Left; Tree Right; }T1[MaxTree], T2[MaxTree];
Left and Right are subscripts, not pointers, so when there are no left or right children, both Left and Right are - 1, not NULL.
The order of ABCD in the array is not necessarily certain, so it can be changed at will. For example, the tree above can also be expressed as:
Similarly, the static list representation of a tree in a structured array is not unique, that is, flexibility.
How to determine the root node by static linked list?
The four nodes above are placed on the corresponding positions of subscripts 0, 1, 3 and 4, which appear in the structure array and which do not. The right child of A is the node corresponding to 0, that is, 0, 3 and 4 are used, only 1 is not used. So the corresponding node of 1 is the root node.
Program Framework Building
int main() { Tree R1,R2; R1 = BuildTree(T1); //T1 and T2 are previously defined structural arrays, global variables R2 = BuildTree(T2); if(Isomorphic(R1,R2)) printf("Yes\n"); else printf("No\n"); return 0; }
How to Build Binary Trees
According to the meaning of the title and the input examples:
8 A 1 2 B 3 4 C 5 - D - - E 6 - G 7 - F - - H - -
Enter the number of nodes first, then the letters stored in the nodes in turn, and the number of the left and right child nodes of the nodes, so the code is as follows:
Tree BuildTree(struct TreeNode T[]) { ... scanf("%d\n", &N); //Number of input nodes if(N) { ...... for(i = 0; i < N; i++) { scanf("%c %c %c\n", &T[i].Element, &cl, &cr); //Enter the left and right child numbers as characters, and then process them into integers. ...... } ...... Root = ??? //How to determine the root node? There are no left(cl) and right(cr) nodes in T[i] pointing to it. Only one. } return Root; }
The purpose of the BuildTree function is to create a tree and return the root node of the tree. So what is the root of this? You can scan the structure array once to see which subscript corresponds to which node does not point to it.
Tree BuildTree(struct TreeNode T[]) { ... scanf("%d\n", &N); //Number of input nodes if(N) { for(i = 0; i < N; i++) check[i] = 0; //Array check corresponds to n nodes for(i = 0; i < N; i++) { scanf("%c %c %c\n", &T[i].Element, &cl, &cr); //Enter the left and right child numbers as characters, and then process them into integers. if(cl != "-") //Left son is not empty { T[i].Left = cl-'0'; check[T[i].Left] = 1; //If the left of a node points to a location, check for that location is set to 1. } else T[i].Left = Null; if(cr != '-') //Number corresponding to the right son { T[i].Right = cr-'0'; check[T[i].Right] = 1; } else T[i].Right = Null; } //At the end of the loop, the root node is where the corresponding value in the check array is zero. for(i = 0; i < N; i++) if(!check[i]) break; Root = i } return Root; }
How to Discriminate Binary Tree Isomorphism
int Isomorphic(Tree R1, Tree R2) { if(R1 == Null) && (R2 == Null) //Both trees are empty. return 1; if((R1 == Null) && (R2 != Null)) || ((R1 != Null) && (R2 == Null))) //One tree is empty, the other is not empty. return 0; if(T1[R1].Element != T2[R2].Element) //Root nodes are different return 0; if((T1[R1].Left == Null) && (T2[R2].Left == Null)) //There are no left children. return Isomorphic(T1[R1].Left, T2[R2].Left); if(((T1[R1].Left != Null) && (T2[R2].Left != Null)) && (T1[T1[R1].Left].Element == T2[T2[R2].Left].Element)) //If the left child is not empty at the same time, and the Element s are the same return (Isomorphic(T1[R1].Left, T2[R2].Left) && Isomorphic(T1[R1].Right, T2[R2].Right)); //Judging whether the left side is isomorphic and the right side is isomorphic else //The case included in this else is: //1. If the elements of the left subtree of the two root nodes are different, the left and right isomorphism and the right and left isomorphism are judged. //2. If the left subtree of one tree is empty and the right subtree of another tree is empty, we should also judge this way. return (Isomorphic(T1[R1].Left, T2[R2].Right) && Isomorphic(T1[R1].Right, T2[R2].Left)); }
Complete code
#include <stdio.h> #include <stdlib.h> #define MaxTree 10 #define ElementType char #define Tree int struct TreeNode { ElementType element; Tree left; Tree right; }T1[MaxTree], T2[MaxTree]; Tree buildTree(struct TreeNode T[]); int isomorphic(Tree t1, Tree t2); int main() { Tree r1,r2; r1 = buildTree(T1); r2 = buildTree(T2); if (isomorphic(r1, r2)) printf("Yes\n"); else printf("No\n"); return 0; } Tree buildTree(struct TreeNode T[]) { int n; scanf("%d\n", &n); Tree root = -1; if(n) { Tree check[MaxTree]; int i; char cl,cr; for(i = 0; i < n; i++) check[i] = 0; for(i = 0; i < n; i++) { scanf("%c %c %c\n", &T[i].element, &cl, &cr); if(cl != '-') { T[i].left = cl - '0'; check[T[i].left] = 1; } else { T[i].left = -1; } if(cr != '-') { T[i].right = cr - '0'; check[T[i].right] = 1; } else { T[i].right = -1; } } for (i = 0; i < n; i++){ if(!check[i]) break; } root = i; } return root; } int isomorphic(Tree r1, Tree r2) { if(r1 == -1 && r2 == -1) return 1; if((r1 == -1 && r2 != -1) || (r1 != -1 && r2 == -1)) return 0; if(T1[r1].element != T2[r2].element) return 0; if(T1[r1].left == -1 && T2[r2].left == -1) return isomorphic(T1[r1].right, T2[r2].right); if((T1[r1].left != -1) && (T2[r2].left != -1) && T1[T1[r1].left].element == T2[T2[r2].left].element) return isomorphic(T1[r1].left, T2[r2].left) && isomorphic(T1[r1].right, T2[r2].right); else return isomorphic(T1[r1].left, T2[r2].right) && isomorphic(T1[r1].right, T2[r2].left); }
ctrl+z ends the input.
Operation results: