树三道OJ题目

1.树的层号表示法
根据树的层号表示建树,打印树的后序遍历序列

样例输入:
5
(0,A) (1,B) (2,D) (2,E) (1,C)
样例输出:
DEBCA

#include <bits/stdc++.h>
#define maxn 30
#define INF 0x3f3f3f3f

using namespace std;

struct Dnode
{
    char data;
    int level;
};

struct Node
{
    char data;
    int level;
    Node *child[maxn];
    Node *parent;
    Node(Dnode a)
    {
        data = a.data;
        level = a.level;
        for (int i=0; i<maxn; i++)
            child[i] = NULL;
        parent = NULL;
    }
};
Dnode a[maxn];

Node* build_tree(Dnode *a, int n)
{
    Node *root, *p, *q;
    if (n < 1) return NULL;
    root = new Node(a[0]);
    p = root;
    for (int i=1; i<n; i++)
    {
        q = new Node(a[i]);
        while (p->level >= q->level)
            p = p->parent;
        q->parent = p;
        int j = -1;
        while (p->child[++j] != NULL);
        p->child[j] = q;
        p = q;
    }
    return root;
}

void postorder(Node *root)
{
    if (root)
    {
        for (int i=0; i<maxn; i++)
        {
            if (root->child[i])
                postorder(root->child[i]);
            else break;
        }
        printf("%c", root->data);
    }
}

int main()
{
    int n;
    scanf("%d", &n);
    getchar();
    for (int i=0; i<n; i++)
    {
        scanf("(%d,%c)", &a[i].level, &a[i].data);
        getchar();
    }
    Node *root = build_tree(a, n);
    postorder(root);
    putchar('\n');
    return 0;
}

2. 还原二叉树
给定一棵二叉树的先序遍历和中序遍历,要求计算出该二叉树的高度。

样例输入:
9
ABDFGHIEC
FDHGIBEAC
输出:
5

#include <bits/stdc++.h>

using namespace std;

string s1,s2;

typedef struct node{
    char data;
    struct node* lchild;
    struct node* rchild;
}tree;

tree* creat()
{   tree*p=new tree;
    p->lchild=p->rchild=NULL;
    return p;
}

tree* recover(int x1,int x2,int y1,int y2){
    tree*p=creat();
    p->data=s1[x1];
    for(int j=y1;j<=y2;j++){
        if(s1[x1]==s2[j])
        {   if(j!=y1)
                p->lchild=recover(x1+1,x1+j-y1,y1,j-1);
            if(j!=y2)
                p->rchild=recover(x1+j-y1+1,x2,j+1,y2);
            break;
        }
    }
    return p;
}

int depth(tree *t)
{
    if(t==NULL) return 0;
    int m=depth(t->lchild);
    int n=depth(t->rchild);
    if(m>n)
        return (m+1);
    else
        return (n+1);

}

int main()
{
    int n;
    cin>>n;
    cin>>s1>>s2;
    tree* p=recover(0,s1.size()-1,0,s2.size()-1);
    cout<<depth(p)<<endl;
    return 0;
}
3. 最小权值路径
已知一棵二叉树的中序遍历和后序遍历,从根结点到每个叶子结点存在一条路径,你需要找到其中权值最小的路径(路径的权值是在该路径上的所有结点的权值之和)并输出该叶子结点的权值(1≤结点数≤10000)

样例输入:
7 8 11 3 5 16 12 18
8 3 11 7 16 18 12 5
样例输出:
3

#include <bits/stdc++.h>

const int INF = 1000000;

struct node {		// 二叉树结点
	int data;		// 数据域
	node* left;		// 左孩子
	node* right;	// 右孩子
};

node* build(int* in, int* post, int il, int ih, int pl, int ph) {
// 根据中序遍历in[il, ih]和后序遍历post[pl, ph]构造二叉树
	if(il>ih) {	// 空树
		return NULL;
	}
	node* root = (node*)malloc(sizeof(node));	// 根节点
	root->data = post[ph];
	// 在中序遍历中寻找根节点,然后划分左右子树
	int rootInd = il;
	while(in[rootInd] != root->data) rootInd++;
	int llen = rootInd - il;	// 左子树的长度
	int rlen = ih - rootInd;
	root->left = build(in, post, il, il+llen-1, pl, pl+llen-1);	// 递归构造左子树
	root->right = build(in, post, rootInd+1, ih, pl+llen, ph-1);	// 递归构造右子树
	return root;
}


int getNum(char s[], int len, int a[]) {
// 将长度为len的字符串解析为整型数组,并返回长度
	int num = 0;	// 保存解析的数字
	int ind = 0;	// a的下标
	for(int i=0; i<len; i++) {
		if(s[i] == ' ') {	// 空格为分割符,当前数字解析完成
			a[ind++] = num;
			num = 0;	// 方便解析下一个数字
		} else {	// 数字
			num = num * 10 + s[i] - '0';
		}
	}
	a[ind++] = num;	// 保存最后一个数字
	return ind;
}

int minPath = INF;
int minnode;
void dfs(node* u, int sum) {
// 先序遍历二叉树,sum记录当前结点(不包含)到根节点的权值和
	if(u!=NULL) {	// 非空结点
		if(u->right ==NULL && u->left ==NULL) {	// 遍历到叶子结点
			if(sum+u->data < minPath || (sum+u->data == minPath && u->data < minnode)) {	// 找到更“优”叶子结点
				minPath = sum+u->data;
				minnode = u->data;
			}
		}
		dfs(u->left, sum+u->data);	// 递归遍历左子树
		dfs(u->right, sum+u->data);	// 递归遍历右子树
	}
}

int main() {
	char s1[4000], s2[4000];
	int in[10000], post[10000];	// 中序和后序
	int numcnt;
	while(gets(s1) && gets(s2)) { // 接受两行字符串
		getNum(s1, strlen(s1), in);
		numcnt = getNum(s2, strlen(s2), post);
		node* root = build(in, post, 0, numcnt-1, 0, numcnt-1);	// 构造二叉树
		minPath = INF; 	// 每次遍历都有初始化
		minnode = root->data;
		dfs(root, 0);
		printf("%d\n", minnode);
	}

	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值