#include <stdio.h>
#include <stdlib.h>
#define MAX_SIZE 100
// 二叉树结点定义
typedef struct BiTNode {
char data;
struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;
// 栈结构定义
typedef struct {
BiTree data[MAX_SIZE];
int top;
} Stack;
// 初始化栈
void InitStack(Stack *S) {
S->top = -1;
}
// 判断栈空
int StackEmpty(Stack *S) {
return S->top == -1;
}
// 入栈
void Push(Stack *S, BiTree p) {
if (S->top == MAX_SIZE - 1) return;
S->data[++S->top] = p;
}
// 出栈
BiTree Pop(Stack *S) {
if (StackEmpty(S)) return NULL;
return S->data[S->top--];
}
// 获取栈顶元素
BiTree GetTop(Stack *S) {
if (StackEmpty(S)) return NULL;
return S->data[S->top];
}
/********************** 前序遍历 **********************/
void PreOrderTraverse(BiTree T) {
if (T == NULL) return;
Stack S;
InitStack(&S);
BiTree p = T;
while (p || !StackEmpty(&S)) {
if (p) {
printf("%c ", p->data); // 访问根节点
Push(&S, p); // 根节点入栈
p = p->lchild; // 遍历左子树
} else {
p = Pop(&S); // 出栈
p = p->rchild; // 遍历右子树
}
}
}
/********************** 中序遍历 **********************/
void InOrderTraverse(BiTree T) {
if (T == NULL) return;
Stack S;
InitStack(&S);
BiTree p = T;
while (p || !StackEmpty(&S)) {
if (p) {
Push(&S, p); // 根节点入栈
p = p->lchild; // 遍历左子树
} else {
p = Pop(&S); // 出栈
printf("%c ", p->data); // 访问根节点
p = p->rchild; // 遍历右子树
}
}
}
/********************** 后序遍历 **********************/
void PostOrderTraverse(BiTree T) {
if (T == NULL) return;
Stack S;
InitStack(&S);
BiTree p = T, r = NULL; // r用于记录最近访问过的节点
while (p || !StackEmpty(&S)) {
if (p) {
Push(&S, p);
p = p->lchild; // 走到最左边
} else {
p = GetTop(&S); // 获取栈顶元素
if (p->rchild && p->rchild != r) { // 右子树存在且未被访问
p = p->rchild;
Push(&S, p);
} else {
p = Pop(&S); // 弹出节点
printf("%c ", p->data); // 访问该节点
r = p; // 记录最近访问过的节点
p = NULL; // 节点访问完后,重置p指针
}
}
}
}
// 创建二叉树(按前序遍历输入)
void CreateBiTree(BiTree *T) {
char ch;
scanf("%c", &ch);
if (ch == ' ') {
*T = NULL;
} else {
*T = (BiTree)malloc(sizeof(BiTNode));
(*T)->data = ch;
CreateBiTree(&(*T)->lchild);
CreateBiTree(&(*T)->rchild);
}
}
代码说明:
-
前序遍历非递归算法:
-
访问根节点
-
将根节点入栈
-
遍历左子树
-
当左子树为空时,出栈并遍历右子树
-
-
中序遍历非递归算法:
-
将根节点入栈
-
遍历左子树
-
当左子树为空时,出栈并访问根节点
-
遍历右子树
-
-
后序遍历非递归算法:
-
使用一个指针r记录最近访问过的节点
-
需要判断右子树是否已被访问过
-
只有左右子树都被访问后才能访问根节点
-
这三种遍历方式都使用了栈来模拟递归过程,空间复杂度均为O(h),其中h为二叉树的高度。
&spm=1001.2101.3001.5002&articleId=149180420&d=1&t=3&u=91ce276a429740de9fefe7f17b15b4e7)
13万+

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



