本次笔记内容:
练习题-TTA.1 题意理解
练习题-TTA.2 核心算法
题意理解
先来回忆非递归中序遍历:
- Push的顺序为先序遍历;
- Pop的顺序给出中序遍历。
题意:根据一棵树的先序遍历Push与Pop内容,输出这棵树的先序、中序、后序遍历数组。
提示:不需要真正建立一棵树。
根据Push与Pop直接得出先序、中序数组
如上图右侧,6为数组长度,在程序实现中,定义两个数组pre(先序遍历数组)和in(中序遍历数组)。当然,还需要再开一个数组作为堆栈。
根据pre和in生成post
post用于记录后序数组。
- 在先序遍历中,根结点一定是第一个被访问到的;
- 在后序遍历中,根结点一定是最后一个被访问到的;
- 因此post的最后一个元素就是pre的第一个元素,之后便可以分而治之。
如上图,可以通过中序遍历数组in来确定左右子树。这是一个分而治之的递归问题。
C实现
void solve(int preL, int inL, int postL, int n)
{
if (n == 0)
return;
if (n == 1)
{
post[postL] = pre[preL];
return;
}
// 上面的部分最后设计出,解决最小的case
root = pre[preL];
post[postL + n - 1] = root;
for (i = 0; i < n; i++)
if (in[inL + i] == root)
break; // 在in中找根结点
L = i; // 找到根结点后,左边有多少元素
R = n - L - 1; // 找到根结点后,右边有多少元素
solve(preL + 1, inL, postL, L); // 左子树的元素头结点在各数组中的位置
solve(preL + L + 1 +, inL + L + 1, postL + L, R); //右子树同理
}