Promblem:
给定两个二叉树T1和T2,返回T1的某个子树结构是否与T2的结构相等。
Solution:
首相将两棵树进行序列化【切记加上分割符和空节点标记】,
然后使用KMP算法进行两个字符串匹配,判断子树串是否属于原树串即可
Code:
1 #pragma once 2 #include <iostream> 3 #include <string> 4 5 using namespace std; 6 7 struct Node 8 { 9 char c; 10 Node* lchild; 11 Node* rchild; 12 Node(char a) :c(a), lchild(nullptr), rchild(nullptr) {} 13 }; 14 15 void getSequence(string &str, Node* root) 16 { 17 if (root == nullptr) 18 str += "#_"; 19 else 20 { 21 str = str + root->c + "_"; 22 getSequence(str, root->lchild); 23 getSequence(str, root->rchild); 24 } 25 } 26 27 void getIndex(int*& index, string str) 28 { 29 for (int i = 0, p = 0; i < str.length(); ++i) 30 { 31 if (0 == i) 32 index[0] = -1; 33 else if (1 == i) 34 index[i] = 0; 35 else 36 { 37 if (str[i - 1] == str[p]) 38 index[i] = ++p; 39 else if (p > 0) 40 p = index[p]; 41 else 42 index[i] = 0; 43 } 44 } 45 } 46 47 bool isSubTree(Node* root1, Node* root2) 48 { 49 string str1, str2; 50 str1 = str2 = ""; 51 //序列化 52 getSequence(str1, root1); 53 getSequence(str2, root2); 54 //获取子树的前后缀长度 55 int* index = new int[str2.length()]; 56 getIndex(index, str2); 57 58 //使用KMP进行判断 59 int i, j; 60 i = j = 0; 61 while (i < str1.length() && j < str2.length()) 62 { 63 if (str1[i] == str2[j]) 64 { 65 ++i; 66 ++j; 67 } 68 else if (-1 == index[j]) 69 { 70 j = 0; 71 ++i; 72 } 73 else 74 j = index[j]; 75 } 76 delete[] index; 77 return (i <= str1.length() && j >= str2.length()); 78 } 79 80 void Test() 81 { 82 Node *root1, *root2; 83 root1 = new Node('5'); 84 85 root1->lchild = new Node('4'); 86 root1->rchild = new Node('3'); 87 root1->lchild->lchild = new Node('2'); 88 root1->lchild->rchild = new Node('1'); 89 root1->rchild->rchild = new Node('1'); 90 91 root2 = new Node('3'); 92 root2->rchild = new Node('1'); 93 cout << isSubTree(root1, root2) << endl; 94 95 root2 = nullptr; 96 root2 = new Node('4'); 97 root2->lchild = new Node('2'); 98 cout << isSubTree(root1, root2) << endl; 99 }