天梯賽:7-157 二叉搜索樹的結構 (30分)(AC滿分+解析+測試點)

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

歡迎大家批評改正 !!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章