HDU 5444 二叉树

给的序列是二叉树的中序遍历,然后把所有数从小到大排列是该二叉树的先序遍历

然后可以唯一确定这棵二叉树,然后求一下就好,它的任何一个子树,满足左<根<右(这不就是二叉排序树嘛)

找了一个网上的根据先序和中序确定二叉树的版。。。


代码:

#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std;
#define N 1005
char path[N];
struct Node    /* 树结点类型 */
{
	int info;    /* 数据域 */
	struct Node*    parent;    /* 父结点 */
	struct Node*     lchild;    /* 左孩子结点 */
	struct Node*    rchild;    /* 右孩子结点 */
};
typedef struct Node* PNode;
PNode root;
struct Stack        /* 栈结点类型 */
{
	int*    pre;
	int*    in;
	int    n;
	PNode    parent;
};
int myIndex(int seq[], int c)    /* 查找c在seq中的位置,不存在则返回-1 */
{
	int i;
	for (i = 0; seq[i] != 0; ++i)
	{
		if (seq[i] == c)
			return i;
	}
	return -1;
}
/* 创建一棵树,其中pre是前序遍历的结果,in是中序遍历的结果,n是结点总数,parent是所建的树的父结点 */
/* 如果结点数大于0,则创建一个结点并返回指向这个结点的指针,如果等于0,则返回NULL */
/* 具体算法请参照二叉树的前序遍历的非递归算法 */
PNode creattree(int pre[], int in[], int n, PNode parent)
{
	PNode p;
	struct Stack s[N], t;    /* 用来存储参数的栈 */
	int top = 0;        /* 栈顶指针,值为0的时候,栈为空 */
	int i;
	PNode head = NULL;    /* 用来返回的根结点 */
	int done = 0;    /* 标记树有没有完全建立起来,初始化为假 */

	while (!done)    /* 如果树没有建立起来,则要继续进入建立 */
	{

		while (n != 0)        /* n的值不为0,也就是pre和in中都至少还有一个元素的时候 */
		{
			i = myIndex(in, pre[0]);        /* 确定pre的第一个元素,就是父结点在中序遍历结果中的位置 */
			p = new Node();/* 建立一个结点 */
			p->info = pre[0];

			p->parent = parent;
			p->lchild = NULL;
			p->rchild = NULL;
			if (parent != NULL)    /* 当结点的父结点不是空值时,就把parent的左孩子值改成p */
			{
				parent->lchild = p;
			}
			else        /* 如果为空时 */
			{
				head = p;    /* 那么这个结点就是根结点 */
			}

			if (n - i - 1 != 0)    /* 只有前序遍历和中序遍历结果都有元素时,才入栈 */
			{

				t.pre = pre + i + 1;    /* 右子树的前序遍历的结果 */
				t.in = in + i + 1;    /* 右子树的中序遍历的结果 */
				t.n = n - i - 1;    /* 右子树的结点个数 */
				t.parent = p;        /* 右子树的父结点就是当前结点 */
				s[++top] = t;        /* 入栈 */
			}
			pre = pre + 1;        /* 右子树的前序遍历的结果,中序遍历的结果不变 */
			n = i;            /* 只是结点个数减少而已 */
			parent = p;        /* 右子树的父结点就是当前结点 */
		}
		if (top != 0)        /* 当栈不空时,也就是至少还有一个子树的右子树没有建立 */
		{
			t = s[top--];    /* 出栈 */
			pre = t.pre;
			in = t.in;
			n = t.n;
			parent = t.parent;

			i = myIndex(in, pre[0]);
			p = (PNode)(malloc(sizeof(struct Node)));
			p->info = pre[0];
			p->parent = parent;
			p->lchild = NULL;
			p->rchild = NULL;

			if (parent != NULL)
				parent->rchild = p;    /* 注意,现在是在建立右子树 */
			else
				head = p;

			if (n - i - 1 != 0)
			{

				t.pre = pre + i + 1;
				t.in = in + i + 1;
				t.n = n - i - 1;
				t.parent = p;
				s[++top] = t;
			}

			pre = pre + 1;
			n = i;
			parent = p;
		}
		else        /* 栈空了,也就是建立起了这棵树 */
			done = 1;
	}
	return head;
}
void work(int x)
{
	int p = root->info, i = 0;
	PNode pn = root;
	while (p != x)
	{
		if (x < p)
		{
			path[i++] = 'E';
			pn = pn->lchild;
			p = pn->info;
		}
		else
		{
			path[i++] = 'W';
			pn = pn->rchild;
			p = pn->info;
		}
	}
}
int main()
{
	int t;
	scanf("%d", &t);
	while (t--)
	{
		int n, q, tmp;
		int pre[N];
		int in[N];
		scanf("%d", &n);
		for (int i = 0; i < n; ++i)
		{
			scanf("%d", &pre[i]);
			in[i] = i + 1;
		}
		root = creattree(pre, in, n, NULL);
		scanf("%d", &q);
		for (int i = 0; i < q; ++i)
		{
			memset(path, 0, sizeof(char)*N);
			scanf("%d", &tmp);
			work(tmp);
			printf("%s\n", path);
		}
	}
	
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值