二叉树叶子节点到根节点的路径
题目描述
给定一棵二叉树的后序遍历序列 post[s1..t1]
和中序遍历序列 in[s2..t2]
,设计一个算法,输出二叉树中从每个叶子节点到根节点的路径。请使用栈的数据结构解决。
输入格式
输入包括两行:
- 第一行为后序遍历序列
post[s1..t1]
。 - 第二行为中序遍历序列
in[s2..t2]
。
保证构成一棵唯一的二叉树。
输出格式
输出多行,每行表示一条从叶子节点到根节点的路径,路径上的节点按照从叶子节点到根节点的顺序排列。
样例 #1
样例输入 #1
DEBGFCA
DBEAFGC
样例输出 #1
ABD
ABE
ACFG
提示
首先,后序遍历的最后一个元素是树的根。然后,你可以在中序遍历序列中找到这个根,这样就可以确定哪些元素在左子树,哪些在右子树。然后,你可以递归地构造左子树和右子树。
利用栈的特性,可以方便地实现从叶子节点到根节点的路径的输出。在遍历过程中,将路径上的节点压入栈中,当遍历到叶子节点时,就可以将栈中的元素按照出栈顺序输出,即得到从叶子节点到根节点的路径。
思路
先检查传入的二叉树 T
是否存在。如果存在,就将当前节点的数据 T->data
压入栈 stk
。这是因为栈的特性决定了它能够保存从叶子节点到根节点的路径。
接着,检查当前节点是否是叶子节点,即它的左右子树 T->left
和 T->right
是否都不存在。如果是叶子节点,就输出从栈底到栈顶的所有元素,即从根节点到当前叶子节点的路径,然后从栈中弹出当前节点。
如果当前节点不是叶子节点,就递归地对左子树 T->left
和右子树 T->right
调用 findPath
。这样,就可以遍历到所有的叶子节点。
最后,无论当前节点是否是叶子节点,都会在遍历完其所有子树后从栈中弹出当前节点。这是因为在返回到父节点之前,需要清理当前节点的信息,否则会影响其他路径的输出。
算法分析
对于时间复杂度,算法需要遍历二叉树的所有节点,所以时间复杂度为 O ( n ) O(n) O(n),其中 n n n 是二叉树的节点数。空间复杂度主要取决于栈的大小和递归深度,最坏情况下,当二叉树退化为链表时,空间复杂度为 O ( n ) O(n) O(n)。
AC代码
#include <algorithm>
#include <cstring>
#include <iostream>
#define AUTHOR "HEX9CF"
using namespace std;
using Status = int;
using ElemType = char;
const int N = 1e4 + 7;
const int TRUE = 1;
const int FALSE = 0;
const int OK = 1;
const int ERROR = 0;
const int INFEASIBLE = -1;
// const int OVERFLOW = -2;
int n;
ElemType a[N];
struct TreeNode {
ElemType data;
struct TreeNode *left, *right;
};
using BiTree = TreeNode *;
struct Stack {
ElemType data[N];
int top;
};
BiTree createBiTree(char *last, char *mid, int len) {
if (len <= 0) {
return NULL;
}
// 后序序列最后一个节点为根节点
char root = last[len - 1];
// 中序序列中找根节点
int index = 0;
while (mid[index] != root) {
index++;
}
// 创建根节点
BiTree T = (TreeNode *)malloc(sizeof(TreeNode));
T->data = root;
T->left = createBiTree(last, mid, index);
T->right = createBiTree(last + index, mid + index + 1, len - index - 1);
return T;
}
Status initStack(Stack &stk) {
stk.top = 0;
return OK;
}
Status push(Stack &stk, ElemType e) {
if (stk.top >= N) {
return ERROR;
}
stk.data[++stk.top] = e;
return OK;
}
Status pop(Stack &stk) {
if (!stk.top) {
return ERROR;
}
stk.top--;
return OK;
}
ElemType getTop(Stack stk) { return stk.data[stk.top]; }
void findPath(BiTree T, Stack &stk) {
if (T) {
push(stk, T->data);
if (!T->left && !T->right) {
for (int i = 1; i <= stk.top; i++) {
cout << stk.data[i];
}
cout << endl;
pop(stk);
return;
}
findPath(T->left, stk);
findPath(T->right, stk);
pop(stk);
}
}
int main() {
char post[N], in[N];
cin >> post >> in;
BiTree T = createBiTree(post, in, strlen(post));
Stack stk;
initStack(stk);
findPath(T, stk);
return 0;
}
标签:结点,遍历,int,C++,stk,叶子,二叉树,节点
From: https://blog.csdn.net/qq_34988204/article/details/138277694