Q:You have two very large binary trees: T1, with millions of nodes, and T2, with hundreds of nodes. Create an algorithm to decide if T2 is a subtree of T1
A:DFS.
T1当前节点是否与T2的根节点相等。
如果不相等,查看T2是不是T1的左、右子树的子树
如果相等,查看T1的左右子树和T2的左右子树是否一致
#include <iostream>
#include <vector>
using namespace std;
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode() {}
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
//初始化数据
TreeNode *dfs(vector<int> &num, int start, int end) {
if (start == end) {
return NULL;
}
int mid = start + (end-start)/2;
TreeNode *root = new TreeNode(num[mid]);
root->left = dfs(num, start, mid);
root->right = dfs(num, mid+1, end);
return root;
}
TreeNode *sortedArrayToBST(vector<int> &num) {
const int n = num.size();
if (n == 0) {
return NULL;
}
return dfs(num,0,n);
}
//算法实现
bool matchTree(TreeNode *p, TreeNode *q) {
if (!p && !q) {
return true;
}
if (!p || !q) {
return false;
}
if (p->val != q->val) {
return false;
}
return matchTree(p->left, q->left) && matchTree(p->right, q->right);
}
bool subTree(TreeNode *root1, TreeNode *root2) {
if (!root1) {
return false;
}
if (root1->val == root2->val) {
return matchTree(root1, root2);
}
return matchTree(root1->left, root2)||matchTree(root1->right, root2);
}
bool containsTree(TreeNode *root1, TreeNode *root2) {
if (!root2) {
return true;
}
return subTree(root1, root2);
}
vector<int> inorderTraversal(TreeNode *root) {
vector<int> res;
if (!root) {
return res;
}
TreeNode *cur = root;
while (cur) {
if (cur->left == NULL) {
res.push_back(cur->val);
cur = cur->right;
} else {
TreeNode *node = cur->left;
while (node->right && node->right != cur) {
node = node->right;
}
if (!node->right) {
node->right = cur;
cur = cur->left;
} else {
res.push_back(cur->val);
node->right = NULL;
cur = cur->right;
}
}
}
return res;
}
int main() {
vector<int> a;
for (int i = 1; i < 10; i++) {
a.push_back(i);
}
TreeNode *root1 = sortedArrayToBST(a);
a.clear();
a = inorderTraversal(root1);
for (int i = 0; i < a.size(); i++) {
cout<<a[i]<<" ";
}
cout<<endl;
vector<int> b;
for (int i = 1; i < 5; i++) {
b.push_back(i);
}
TreeNode *root2 = sortedArrayToBST(b);
b.clear();
b = inorderTraversal(root2);
for (int i = 0; i < b.size(); i++) {
cout<<b[i]<<" ";
}
cout<<endl;
cout<<containsTree(root1, root2)<<endl;
return 0;
}