P1305 新二叉树

新二叉树

给定二叉树中每个根节点及左右孩子的值,造一棵树,再前序遍历
造树:
给定一个节点,添加其左右孩子
或者给定层序遍历结果,造树

题目描述

输入一串二叉树,输出其前序遍历。

输入格式

第一行为二叉树的节点数 n n n。( 1 ≤ n ≤ 26 1 \leq n \leq 26 1n26)

后面 n n n 行,每一个字母为节点,后两个字母分别为其左右儿子。特别地,数据保证第一行读入的节点必为根节点。

空节点用 * 表示

输出格式

二叉树的前序遍历。

样例 #1

样例输入 #1

6
abc
bdi
cj*
d**
i**
j**

样例输出 #1

abdicj

CODE

#include
using namespace std;
struct Tree { 
    char val; 
    Tree* left; 
    Tree* right;
    Tree(char in=0):val(in),left(nullptr),right(0){}//构造函数,以in作为初始值,默认为0,左右为空指针:0,NULL,nullptr 
}root; //最终建立的树

//建立一个新的结点,以val作为自己的值 
inline Tree* build(char val) { 
    if (val=='*') return NULL; //不建立空节点 
    return new Tree(val);
}
//查找特定根节点函数(中序查找):在传入的当前这棵树(即初始传入查找起点默认为根节点)中找到值为tartget的节点 
Tree* find_cur_root(char target, Tree* cur = &root) {
    if(cur->val==target)return cur;
    Tree* pos = nullptr;
    if(cur->left)pos =find_cur_root(target, cur->left);//左递归
    if(pos)return pos;//中处理逻辑 
    if(cur->right)pos=find_cur_root(target, cur->right);//右递归 
    return pos;
}
//前序遍历 
void preorder(Tree* cur) {
    cout<<cur->val;
    //若左右子树不为空则继续便利 
    if(cur->left) preorder(cur->left);
    if(cur->right)preorder(cur->right);
}
int main() {
    int n;cin>>n;
    char val,l,r;cin>>val>>l>>r;
    root.val=val;
	root.left=build(l);
	root.right=build(r);
    //接下来的输入,第一个字母为当前根节点值,第二三个值为左右子树各自根节点的值 
    for (int i = 1; i < n; ++i) {
        char crval,lsval,rsval;
		cin>>crval>>lsval>>rsval;//current_root_value,left_son_value,right_son_value
        Tree* cr  = find_cur_root(crval,&root);//每一次循环输入后,都先从树根root开始找值为crval的根节点cr(current_root)
        cr->left  = build(lsval);
		cr->right = build(rsval); 
    }
    //树建好了,从树根开始前序 
    preorder(&root);
    return 0;
}

CODE2:非本题(上一个代码才是本题)

突发奇想,写了一个根据层序序列造二叉树再递归遍历的代码

#include
using namespace std;
struct node{
	char val;
	node* left;
	node* right;
	node(char x):val(x),left(NULL),right(NULL){};
};
//根据层序序列构造二叉树!!!!!!!!!!!!!!!!!!!!!!!
void build(node*& cur,queue<char>&layer){
	queue<node*>bitree;//二叉树的层序节点队列 
	cur=new node(layer.front());layer.pop();//以层序值队列头元素(一个值)初始化传入的节点 
	bitree.push(cur);//将层序根节点放入层序节点队列 
	while(!layer.empty()){//只要层序值序列还有值,就应该给层序节点队列的当前头元素的左右子赋值(这个值为层序值序列的头元素pop再头元素) 
		//层序遍历queue是遍历一个弹出一个加入弹出的左右节点
		//反向推导: 
		if(bitree.front()->val!='*'){
		bitree.front()->left = new node(layer.front());layer.pop();bitree.push(bitree.front()->left);
		bitree.front()->right = new node(layer.front());layer.pop();bitree.push(bitree.front()->right);
		bitree.pop();	
		}else{//如果当前节点为空节点,则不应为其分配左右孩子,故值序列不动,节点序列弹出此空节点 
			bitree.pop();
		}
	}
}
void preorder(node* cur){//先序遍历 
	if(cur->val=='*')return;//空节点退出
	//单层循环的逻辑 
	cout<<cur->val;//处理节点,中 
	preorder(cur->left);//左 
	preorder(cur->right);//右 
}
int main(){
/*  ios::sync_with_stdio(0);cin.tie(nullptr);cout.tie(nullptr);
	int n;cin>>n;
	char tree[3+2*(n-1)];queuelayerorder;
	cin>>tree[0]>>tree[1]>>tree[2];
	layerorder.push(tree[0]);layerorder.push(tree[1]);layerorder.push(tree[2]);
	--n;int index=3;char temp; 
	while(n--){
		cin>>temp>>tree[index]>>tree[index+1];
		layerorder.push(tree[index]);
		layerorder.push(tree[index+1]);
		index+=2;
	}*/ 
	
//层序序列的各节点值已得到 
	//	while(!layerorder.empty()){cout<
//问题变为:给定层序遍历二叉树值的序列layerorder,构造一棵二叉树
	node* root;//初始化一个节点 
	build(root,layerorder);//将此节点传入二叉树构造函数中,此节点为根节点 
	//以root为根节点的二叉树构造完毕
	//问题转化为,给定二叉树根节点,先序遍历次二叉树 
	preorder(root);
	return 0;
}
/*
例如:
8
abc
b*d
cef
dgh
e**
f**
g**
h**
造成层序序列:abc*defgh
前序遍历二叉树abdghcef
*/ 

你可能感兴趣的:(二叉树,洛谷刷题,算法,数据结构)