【复旦大学历年机试题】2023-01(二叉树)
·

题目:给你两棵二叉树 root 和 subRoot 。检验 root 中是否包含和 subRoot 具有相同结构和节点值的子树。如果存在,返回 true ;否则,返回 false 。注意二叉树 tree 的一棵子树包括 tree 的某个节点和这个节点的所有后代节点。tree 也可以看做它自身的一棵子树。
题解:不知道具体怎么给输入的,这里我按照完全二叉树的方式给两个输入,第一行是root树,第二行是subroot树,-1表示空结点。为了方便,将两棵树的数组设为全局变量。设置两个函数,一个PreOrder用于遍历root(什么遍历方式都可以,这里采用前序遍历),另一个Compare用于比对root与subroot。
输入示例:
1 2 3 4 -1 5 6
2 4 -1
输出示例:
true
代码(C++):
#include <bits/stdc++.h>
using namespace std;
vector<int> root;
vector<int> subroot;
bool flag = false; // 标志是否找到符合条件的子树
bool Compare(int rindex, int sindex){
if(rindex >= root.size() && sindex >= subroot.size()) return true; // 空结点一致
if((rindex < root.size() && sindex >= subroot.size()) || (rindex >= root.size() && sindex < subroot.size())) return false; // 空结点与非空结点一致
if(root[rindex] != subroot[sindex]) return false; // 非空结点与非空结点值不同,不一致
bool lc = Compare((rindex + 1) * 2 - 1,(sindex + 1) * 2 - 1); // 左子树比较
bool rc = Compare((rindex + 1) * 2,(sindex + 1) * 2); // 右子树比较
return lc && rc;
}
void PreOrder(int index){
if(index >= root.size() || flag) return; // 终止条件是遍历到空结点或者已找到符合条件的子树
if(Compare(index,0)){
flag = true;
}
PreOrder((index + 1) * 2 - 1); // 遍历左子树
PreOrder((index + 1) * 2); // 遍历右子树
}
int main(){
int data; // 输入数据
// 输入
while(cin >> data){
root.push_back(data);
if(getchar() == '\n') break;
}
while(cin >> data){
subroot.push_back(data);
if(getchar() == '\n') break;
}
// 主体
PreOrder(0);
// 输出
if(flag){
printf("true");
}else{
printf("false");
}
return 0;
}
写在后面
这个专栏主要是我在刷题的过程中总结的一些笔记,因为我学的也很一般,如果有错误和不足之处,还望大家在评论区指出。希望能给大家的学习带来一点帮助,共同进步!!!
更多推荐


所有评论(0)