二叉树的非递归遍历代码(前序、中序、后序)

#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);
    }
}

代码说明:

  1. 前序遍历非递归算法

    • 访问根节点

    • 将根节点入栈

    • 遍历左子树

    • 当左子树为空时,出栈并遍历右子树

  2. 中序遍历非递归算法

    • 将根节点入栈

    • 遍历左子树

    • 当左子树为空时,出栈并访问根节点

    • 遍历右子树

  3. 后序遍历非递归算法

    • 使用一个指针r记录最近访问过的节点

    • 需要判断右子树是否已被访问过

    • 只有左右子树都被访问后才能访问根节点

这三种遍历方式都使用了栈来模拟递归过程,空间复杂度均为O(h),其中h为二叉树的高度。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xienda

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值