7-157 二叉搜索樹的結構 (30分)
輸入樣例:
5
2 4 1 3 0
8
2 is the root
1 and 4 are siblings
3 and 0 are on the same level
2 is the parent of 4
3 is the left child of 4
1 is the right child of 2
4 and 0 are on the same level
100 is the right child of 3
輸出樣例:
Yes
Yes
Yes
Yes
Yes
No
No
No
測試點:
下圖參考博客:https://blog.csdn.net/Dream_Weave/article/details/82744830
思路
1. 首先讀者要知道什麼是二叉搜索樹,它是怎麼構造的,特點等等。。。
2. 二叉搜索樹構造好了,定義結構體point保存每個結點對應的父節點,深度。
使用map對輸入的值標記,map<int,point>。(爲什麼不直接用數組下標呢?因爲輸入的數據可能很大,直接用數組下標標記內存會超)
3. 對輸入的字符串進行處理,採用的是sscanf(很好用啦)。具體用法讀者自行了解(當然有很多方法,讀者自行選擇)。
注意: (測試點2)當輸入字符串中的結點不存在時,需要注意一下,此時應該輸出No。解釋: 會有一種情況,這兩個結點都不存在時,可能它們的深度都是默認值0,然後就輸出了Yes,其實應該輸出No。(鄙人當時。。。就是這個錯誤找了半天QAQ。。。。)
樣例:
輸入:
5
2 4 1 3 0
2
10 and 20 are on the same level
2 and 10 are on the same level
輸出:
No
No
#include<bits/stdc++.h>
using namespace std;
typedef struct TNode{
int data;
struct TNode *right;
struct TNode *left;
} *BinTree;
BinTree bst=NULL;
struct point{
int fa,d=-1;
};
map<int,point> p; //map標記輸入的值,節省內存,不會段錯誤
BinTree insert(BinTree &bst, int x, int fa, int dept){ //插入新結點,構造二叉搜索樹
if(!bst){
bst=(BinTree)malloc(sizeof(TNode));
bst->data=x;
bst->left = bst->right = NULL;
if(fa!=-1){
p[x].d=dept; //深度
p[x].fa=fa; //x的父節點
}
}
else{
if(x < bst->data){ //x在左子樹上
bst->left = insert(bst->left, x, bst->data, dept+1);
}
else if(x > bst->data){ //x在右子樹上
bst->right = insert(bst->right, x, bst->data, dept+1);
}
}
return bst;
}
int main(){
int n,m,x,root;
cin>>n;
for(int i=0; i<n; i++){
cin>>x;
insert(bst, x, -1, 0); //構造二叉搜索樹
}
root=bst->data; //根結點
p[root].fa=-1;
p[root].d=0;
cin>>m;
getchar();
while(m--){
int x,y=-1,flag=0;
string s;
getline(cin,s);
if(s.find("root")!=string::npos){ //判斷是否爲根
sscanf(s.c_str(),"%d is the root",&x);
if(root==x) flag=1;
}
else if(s.find("siblings")!=string::npos){ //判斷是否爲兄弟
sscanf(s.c_str(),"%d and %d are siblings",&x,&y);
if(p[x].fa == p[y].fa)flag=1;
}
else if(s.find("parent")!=string::npos){ //判斷x是否爲y的父節點
sscanf(s.c_str(),"%d is the parent of %d",&x,&y);
if(p[y].fa == x)flag=1;
}
else if(s.find("left")!=string::npos){ //判斷y是否爲x的左孩子
sscanf(s.c_str(),"%d is the left child of %d",&x,&y);
if(p[x].fa==y&&x<y)flag=1;
}
else if(s.find("right")!=string::npos){ //判斷y是否爲x的右孩子
sscanf(s.c_str(),"%d is the right child of %d",&x,&y);
if(p[x].fa==y&&x>y)flag=1;
}else if(s.find("same")!=string::npos){ //是否在同一層
sscanf(s.c_str(),"%d and %d are on the same level",&x,&y);
if(p[x].d==p[y].d)flag=1;
}
if(p[x].d==-1||p[y].d==-1&&y!=-1)flag=0;//判斷輸入的結點是否存在,不存在輸出No
if(flag) cout<<"Yes\n";
else cout<<"No\n";
}
return 0;
}
代碼中:sting中find()函數和string::npos(解析)
https://blog.csdn.net/weixin_43581819/article/details/104187948
歡迎大家批評改正 !!!