1.算法思想
借助栈来实现二叉树的非递归先后序遍历。访问某结点后,要将该结点的指针添加到栈中,以便能够通过该结点找到他的右子树,以如下一个简易的的二叉树作为示例:

算法思想为:
- 设置currentNode,visitedNode分别表示当前正在访问的结点以及上一次访问过的结点,初始值为根结点root。
- 当currentNode不为空或者栈不为空时,说明还有结点没访问完,因此判断当前结点:
2.1 如果currentNode不为空,则将其添加到栈中,然后访问其左子树。
2.2 如果currentNode为空,说明左子树已经访问完毕,获取栈顶结点访问其右子树。 - 如果右子树存在且不是上次访问的结点,则将该右子树添加到栈中,然后继续访问其左子树。否则输出当前结点出栈,并修改currentNode和visitedNode。
2.定义结构体
typedef struct BiNode {
int data;
struct BiNode *lchild, *rchild;
} BiNode, *BiTree;
3.函数实现
/*后序遍历非递归*/
void PostOrder(BiTree root) {
BiNode *S[MAXSIZE];//结点栈,用于存放结点
int top = -1;//栈顶指针
BiNode *currentNode = root;//当前结点
BiNode *visitedNode = root;//上次访问的结点
//当当前结点不为空或栈不为空,即还有元素时,访问
while (currentNode || top != -1) {
//从根结点出发,寻找到左下结点
while (currentNode != NULL) {
S[++top] = currentNode;//将当前结点入栈
currentNode = currentNode->lchild;//指向左孩子,继续
}
//找到了最左下结点,退出循环
currentNode = S[top];//栈顶元素为最左下结点
//当右孩子存在且不是上次访问的结点
if (currentNode->rchild != NULL && currentNode->rchild != visitedNode) {
currentNode = currentNode->rchild;//指向右结点
} else {
//否则说明该结点无左孩子,右孩子要么不存在要么已被访问,所以输出该结点
printf("%d\t", currentNode->data);
visitedNode = currentNode;//修改访问结点为当前结点
currentNode = NULL;//当前结点为空
S[top--];//出栈
}
}
}
4.运行结果

5 .完整代码
#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 100
//定义结构体
typedef struct BiNode {
int data;
struct BiNode *lchild, *rchild;
} BiNode, *BiTree;
/*后序遍历非递归*/
void PostOrder(BiTree root) {
BiNode *S[MAXSIZE];//结点栈,用于存放结点
int top = -1;//栈顶指针
BiNode *currentNode = root;//当前结点
BiNode *visitedNode = root;//上次访问的结点
//当当前结点不为空或栈不为空,即还有元素时,访问
while (currentNode || top != -1) {
//从根结点出发,寻找到左下结点
while (currentNode != NULL) {
S[++top] = currentNode;//将当前结点入栈
currentNode = currentNode->lchild;//指向左孩子,继续
}
//找到了最左下结点,退出循环
currentNode = S[top];//栈顶元素为最左下结点
//当右孩子存在且不是上次访问的结点
if (currentNode->rchild != NULL && currentNode->rchild != visitedNode) {
currentNode = currentNode->rchild;//指向右结点
} else {
//否则说明该结点无左孩子,右孩子要么不存在要么已被访问,所以输出该结点
printf("%d\t", currentNode->data);
visitedNode = currentNode;//修改访问结点为当前结点
currentNode = NULL;//当前结点为空
S[top--];//出栈
}
}
}
int main(int argc, char const *argv[]) {
BiTree l1 = (BiTree)malloc(sizeof(BiNode));
BiNode *l2 = (BiNode *)malloc(sizeof(BiNode));
BiNode *l3 = (BiNode *)malloc(sizeof(BiNode));
BiNode *l4 = (BiNode *)malloc(sizeof(BiNode));
l1->data = 1;
l2->data = 2;
l3->data = 3;
l4->data = 4;
l1->lchild = l2;
l1->rchild = l3;
l2->lchild = NULL;
l2->rchild = l4;
l3->lchild = NULL;
l3->rchild = NULL;
l4->lchild = NULL;
l4->rchild = NULL;
printf("后序遍历的结果为:\n");
PostOrder(l1);
return 0;
}
本文介绍了如何使用栈进行非递归的二叉树后序遍历算法,通过设置当前节点和已访问节点,不断将节点入栈并遍历其左子树,直到找到最左下节点,然后访问右子树或输出节点数据。详细解释了算法思想,并给出了C语言的实现代码。
4410

被折叠的 条评论
为什么被折叠?



