//
// Created by Cauchyshy on 2023/5/23.
//
/*
* 后序遍历的非递归代码 需要判断栈顶元素有无左右节点 所以需要一个栈顶函数 不删除的
* 后序遍历判断结束很简单 只要栈为空就结束 这也是跟前面两个遍历的区别
* */
#include <iostream>
#include <cstdio>
using namespace std;
// 树的深度 4 就行 这里我们的例子是4 跟自己的层数一样即可
#define TREE_DEEP 5
struct treeNode {
int a; // 数据成员
struct treeNode *pFather; // 父节点
struct treeNode *pLeft; // 左孩子
struct treeNode *pRight; // 右孩子
};
// 由于不需要前后指针 直接用树叶指针类型即可 装树几点地址即可
struct treeNode *stack[TREE_DEEP] = {0};
// 用下标最栈顶指示符即可 栈顶
int stacktop = -1; // -1表示空栈 因为下标从0开始 0元素就是一个栈内元素了
// 入栈
void push(struct treeNode *node) {
if (NULL == node)
return ;
stacktop++; // 栈顶标记先自加1
stack[stacktop] = node; // 然后对栈顶赋值
}
//出栈
struct treeNode * pop(void) {
if (stacktop == -1)
return NULL;
int pre = stacktop;
stacktop--;
return stack[pre];
}
// 后序遍历 递归写法
void pos_look(struct treeNode *root) {
if (root != NULL) {
pos_look(root->pLeft);
pos_look(root->pRight);
printf("%d ", root->a);
}
}
// 后序遍历数组栈写法
void posLookByArray(struct treeNode *root) {
if (NULL == root)
return ;
struct treeNode *t = root;
struct treeNode *pre = NULL; // 记录上一个弹出的节点
while (1) {
// 左子树入栈
while (t != NULL) {
push(t);
t = t->pLeft;
}
if (-1 == stacktop) // 栈空跳出循环
break;
// 1.没有右子树 出栈
// 2.有右子树 但是刚才已经出栈过了
if (NULL == stack[stacktop]->pRight || pre == stack[stacktop]->pRight) {
pre = pop();
printf("%d ", pre->a);
} else {
// 否则右子树入栈 栈顶的右子树
t = stack[stacktop]->pRight;
}
}
}
int main() {
struct treeNode t1 = { 1 };
struct treeNode t2 = { 2 };
struct treeNode t3 = { 3 };
struct treeNode t4 = { 4 };
struct treeNode t5 = { 5 };
struct treeNode t6 = { 6 };
struct treeNode t7 = { 7 };
struct treeNode t8 = { 8 };
struct treeNode t9 = { 9 };
struct treeNode t10 = { 10 };
// 链接
t1.pLeft = &t2;
t1.pRight = &t3;
t1.pFather = NULL;
t2.pLeft = &t4;
t2.pRight = &t5;
t2.pFather = &t1;
t3.pRight = &t6;
t3.pLeft = NULL;
t3.pFather = &t1;
t4.pLeft = NULL;
t4.pRight = NULL;
t4.pFather = &t2;
t5.pLeft = &t7;
t5.pRight = &t8;
t5.pFather = &t2;
t6.pLeft = &t9;
t6.pRight = &t10;
t6.pFather = &t3;
t7.pLeft = NULL;
t7.pRight = NULL;
t7.pFather = &t5;
t8.pLeft = NULL;
t8.pRight = NULL;
t8.pFather = &t5;
t9.pLeft = NULL;
t9.pRight = NULL;
t9.pFather = &t6;
t10.pLeft = NULL;
t10.pRight = NULL;
t10.pFather = &t6;
printf("递归后序遍历:\n");
pos_look(&t1);
printf("\n数组栈后序遍历写法:\n");
posLookByArray(&t1);
return 0;
}