PTA P9 中序遍历树并判断是否为二叉搜索树

对给定的有N个节点(N>=0)的二叉树,给出中序遍历序列,并判断是否为二叉搜索树。

题目保证二叉树不超过200个节点,节点数值在整型int范围内且各不相同。

输入格式:
第一行是一个非负整数N,表示有N个节点

第二行是一个整数k,是树根的元素值

接下来有N-1行,每行是一个新节点,格式为r d e 三个整数,

r表示该节点的父节点元素值(保证父节点存在);d是方向,0表示该节点为父节点的左儿子,1表示右儿子;e是该节点的元素值

输出格式:
首先输出二叉树的中序遍历序列,每个元素占一行。对于空树,不输出任何内容。

然后如果给定的树是二叉搜索树,输出Yes 否则输出No

输入样例:
fig.jpg

对于图片中的二叉树:

3
20
20 0 10
20 1 25
输出样例:
10
20
25
Yes

//P9 中序遍历树并判断是否为二叉搜索树
#include<iostream>
#include<map>
#include<vector>
using namespace std;
map<int,map<int,int>> p;
vector<int> v;
bool flag=true;
void bl(int k){
	if(k){
		bl(p[k][0]);
		cout<<k<<endl;
		v.push_back(k);
		bl(p[k][1]);
	}
}
int main()
{
	int n,k;
	cin>>n>>k;
	if(n==0)
	{
		cout<<"Yes\n";
		return 0;
	}
	for(int i=0;i<n-1;i++)
	{
		int r,d,e;
		cin>>r>>d>>e;
		p[r][d]=e;
	}
	bl(k);
	for(int i=0;i<v.size()-1;i++)
	if(v[i]>=v[i+1])
	flag=false;
	if(flag)
	cout<<"Yes\n";
	else
	cout<<"No\n";
}

上面这个只是题目的一种解法而已,显然和题目给人的印象解法不同。也是顺便复习一下,加深下影响,楼主用正规的解法,也就是建树的方式来解答此题。

```cpp
//P9的常规解法
#include<iostream>
#include<vector>
using namespace std;
vector<int> v;
int r;
typedef struct tree* BT;
struct tree{
	int data;
	BT left;
	BT right;
};
BT wz=new tree();// wz用来记住r的位置 
void insert(BT root)
{
	if(root){
		insert(root->left);
		if(root->data==r)
		{
			wz=root;
			return;
		}
		insert(root->right);
	}	
}
void bl(BT root)
{
	if(root){
		bl(root->left);
		cout<<root->data<<endl;
		v.push_back(root->data);
		bl(root->right);
	}
}
int main()
{
	int n,k;
	cin>>n;
	if(n==0)
	{
		cout<<"Yes\n";
		return 0;
	}
	cin>>k;
	BT root=new tree();
	root->data=k;
	root->left=NULL;
	root->right=NULL;
	for(int i=0;i<n-1;i++)
	{
		int d,e;
		cin>>r>>d>>e;
		BT node=new tree();
		insert(root);
		node=wz;
		if(d==0)
		{
			BT t=new tree();
			node->left=t;
			t->data=e;
			t->left=NULL;
			t->right=NULL;
		}
		else
		{
			BT t=new tree();
			node->right=t;
			t->data=e;
			t->left=NULL;
			t->right=NULL;
		}
	}
	bl(root);
	bool flag=true;
	for(int i=0;i<v.size()-1;i++)
	{
		if(v[i]>=v[i+1])
		flag=false;
	}
	if(flag)
	cout<<"Yes\n";
	else
	cout<<"No\n";
} 


这就是常规解法了,没什么提示的,就是注意空树也是二叉搜索树就好了。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 题目描述: 给定一棵二叉树的后序遍历和中序遍历,请输出该二叉树的先序遍历。 输入格式: 第一行包含一个正整数 N(≤30),表示中结点个数。 第二行包含 N 个整数,表示二叉树的后序遍历序列。 第三行包含 N 个整数,表示二叉树中序遍历序列。 输出格式: 输出该二叉树的先序遍历序列。数字间以空格分隔,行末不得有多余空格。 输入样例: 7 2 3 1 5 7 6 4 1 2 3 4 5 6 7 输出样例: 4 2 1 3 6 5 7 解题思路: 根据后序遍历和中序遍历可以确定一棵二叉树,具体方法如下: 后序遍历的最后一个节点为根节点; 在中序遍历中找到根节点,则根节点左侧为左子,右侧为右子; 递归处理左子和右子。 根据上述方法,可以先构建出二叉树,然后再进行先序遍历输出。 代码实现: ### 回答2: 先解释一下的后序、中序、先序遍历是指什么。在上进行遍历时,按照某种顺序依次经过每个节点,被经过的节点就被“遍历”了。根据先经过哪些节点,将遍历分为先序遍历、中序遍历和后序遍历。 先序遍历:先访问根节点,然后递归遍历左子和右子中序遍历:先递归遍历左子,然后访问根节点,再递归遍历右子。 后序遍历:先递归遍历左子,然后递归遍历右子,最后访问根节点。 根据后序遍历和中序遍历输出先序遍历pta的过程如下: 1. 后序遍历最后一个元素一定是的根节点,找到根节点后,可以将中序遍历分为左子和右子两部分。 2. 在中序遍历中,根节点左边的所有元素一定属于左子,右边的所有元素一定属于右子。 3. 因此,可以在后序遍历中找到左子和右子的边界,然后分别对左子和右子递归调用此过程。 4. 直到为空时,输出当前节点即可。 最终,得到的输出结果即为先序遍历。 下面附上示例代码: ``` #include<iostream> #include<vector> #include<algorithm> using namespace std; vector<int> postorder, inorder, preorder; void getPreorder(int postStart, int inStart, int inEnd) { if (inStart > inEnd) return; int rootIndex; for (int i = inStart; i <= inEnd; i++) { if (inorder[i] == postorder[postStart]) { rootIndex = i; break; } } preorder.push_back(postorder[postStart]); getPreorder(postStart-inEnd+rootIndex-1, inStart, rootIndex-1); getPreorder(postStart-1, rootIndex+1, inEnd); } int main() { int n; cin >> n; postorder.resize(n); inorder.resize(n); for (int i = 0; i < n; i++) { cin >> postorder[i]; } for (int i = 0; i < n; i++) { cin >> inorder[i]; } getPreorder(n-1, 0, n-1); cout << preorder[0]; return 0; } ``` 在示例代码中,getPreorder函数的参数分别为后序遍历的起点postStart、中序遍历的起点inStart、中序遍历的终点inEnd。函数内部通过查找根节点,将中序遍历分为左子和右子,然后递归地处理左子和右子。最终得到的preorder就是先序遍历的结果。 在主函数中,通过输入数据构建后序遍历和中序遍历,然后调用getPreorder函数得到先序遍历。输出preorder的第一个元素即为先序遍历的第一个节点pta。 ### 回答3: 先序遍历是指按照“根节点-左子-右子”的顺序遍历一棵二叉树,后序遍历是指按照“左子-右子-根节点”的顺序遍历一棵二叉树中序遍历是指按照“左子-根节点-右子”的顺序遍历一棵二叉树。在已知后序遍历和中序遍历序列的情况下,可以通过递归的方式重新构建一棵二叉树,然后再按照先序遍历的方式输出。 具体实现方式如下: 1. 将后序遍历序列中序遍历序列分别存储到数组postorder和inorder中; 2. 创建一个函数buildTree,该函数接收四个参数,分别为postorder数组的起始位置、终止位置,inorder数组的起始位置和终止位置; 3. 在buildTree函数中,首先取出postorder数组中的最后一个元素作为根节点,然后在inorder数组中找到该根节点的位置,将inorder数组拆分成左子和右子两部分; 4. 在递归过程中,每次将右子在postorder和inorder数组中的起止位置分别传入buildTree函数进行构建,然后再将左子在postorder和inorder数组中的起止位置传入buildTree函数进行构建; 5. 最后,在buildTree函数的最外层穿件一个空的result数组,然后调用buildTree函数构建整棵二叉树,并且将中间节点的值依次存储到result数组中; 6. 最后将result数组从头到尾输出即可。 代码示例: ```python class TreeNode: def __init__(self, val=0, left=None, right=None): self.val = val self.left = left self.right = right def buildTree(postorder, inorder): if not postorder or not inorder: return None root_val = postorder[-1] root = TreeNode(root_val) index = inorder.index(root_val) postorder_left = postorder[:index] postorder_right = postorder[index:-1] inorder_left = inorder[:index] inorder_right = inorder[index+1:] root.left = buildTree(postorder_left, inorder_left) root.right = buildTree(postorder_right, inorder_right) return root def preOrder(root): if not root: return [] res = [root.val] res += preOrder(root.left) res += preOrder(root.right) return res if __name__ == '__main__': postorder = [9, 15, 7, 20, 3] inorder = [9, 3, 15, 20, 7] root = buildTree(postorder, inorder) result = preOrder(root) print(result) ``` 上述代码中,我们首先构建了一个名为TreeNode的类,用于定义二叉树节点;然后定义了一个buildTree函数,其中的逻辑就是上述实现方式中描述的逻辑;最后定义了一个preOrder函数,用于按照先序遍历的方式遍历二叉树并输出先序遍历的结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值