二叉树后续非递归遍历(很多人的盲区?)

大家好,我是Johngo!

今天有在校的粉丝想要C语言实现的树的后续遍历的详细讲解,今天就来看看。
后面给到了所有的代码,可以直接运行!

二叉树后序遍历

二叉树的遍历方式主要由先序遍历、中序遍历和后续遍历,还后就是层次遍历

感受完前两篇的遍历方式,本节来看看后序遍历

后序遍历过程

a. 先序遍历其左子树

b. 先序遍历其右子树

c. 访问根节点

然后就是一直递归下去,在访问到节点的时候,可以进行节点的相关处理,比如说简单的访问节点值

下图是一棵二叉树,我们来手动模拟一下后序遍历过程

image.png

按照上述后序遍历的过程,得到后序遍历序列:

H I D E B F G C A
递归实现

二叉树的后序遍历利用上述的递归思想进行C语言代码实现:

树形结构按照上述树形结构进行初始化

# include <stdio.h>
# include <string.h>
# include <stdlib.h>
# define ElementType char

//结点结构体
typedef struct BinTNode{
    ElementType data; 
    struct BinTNode * left; 
    struct BinTNode * right;
}BinTNode, *BinTree;

// 初始化树形结构
BinTNode * CreateBiTree(BinTNode *T){
    T=(BinTNode*)malloc(sizeof(BinTNode));
    T->data='A';
    T->left=(BinTNode*)malloc(sizeof(BinTNode));
    T->left->data='B';
    T->right=(BinTNode*)malloc(sizeof(BinTNode));
    T->right->data='C';
  
    T->left->left=(BinTNode*)malloc(sizeof(BinTNode));
    T->left->left->data='D';
    T->left->right=(BinTNode*)malloc(sizeof(BinTNode));
    T->left->right->data='E';
    T->left->right->left=NULL;
    T->left->right->right=NULL;  
    T->left->left->left=(BinTNode*)malloc(sizeof(BinTNode));
    T->left->left->left->data='H';
    T->left->left->left->left=NULL;
    T->left->left->left->right=NULL;
    T->left->left->right=(BinTNode*)malloc(sizeof(BinTNode));
    T->left->left->right->data='I';
    T->left->left->right->left=NULL;
    T->left->left->right->right=NULL;
      
    T->right->left=(BinTNode*)malloc(sizeof(BinTNode));
    T->right->left->data='F';
    T->right->left->left=NULL;
    T->right->left->right=NULL;
    T->right->right=(BinTNode*)malloc(sizeof(BinTNode));
    T->right->right->data='G';
    T->right->right->left=NULL;
    T->right->right->right=NULL;

    return T;
}

// 遍历过程中,输出节点值
void printElement(BinTNode * T){
    printf("%c ",T->data);
}

//先序遍历
void PostOrderTraverse(BinTNode * T){
    if (T) {
        PostOrderTraverse(T->left);  //递归访问左孩子
        PostOrderTraverse(T->right); //递归访问右孩子
        printElement(T);             //输出节点值
    }
    // 当节点为空的时候,返回
    return;
}

int main() {
    BinTNode * Tree;
    Tree = CreateBiTree(Tree);	// 初始化树形结构
    printf("后序遍历: ");
    PostOrderTraverse(Tree); 		// 先序递归进行
    printf("\n");   						// 最后换行
    return 0;
}

运行结果:

后序遍历: H I D E B F G C A
非递归实现

相比于之前的先序遍历和中序遍历非递归实现,后序遍历的非递归算法与之前有所不同,后续遍历需要先访问左右子结点后,才能访问该结点,而这也是非递归的难点所在。

考虑了几种实现的方案,这里我给出我认为比较清晰的一个方案供大家参考:借助两个栈(S1和S2)来进行操作

看下面伪代码:

初始化S1的top元素是树的根结点;
while(top1 != -1) {
   
  	将栈顶元素push到S2;
  	if(栈顶元素有孩子结点){
   
      	按照孩子结点的左右顺序push进S1;
    } 
}
循环逐个弹出S2的栈顶元素

伪代码可能看了之后有些不太好懂,但是还算看着清晰吧,下面借助图,一定会思路清晰的(长图发放):

image.png

有了这个思路就应该会很清晰了,下面按照上述思路用C语言实现:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define ElementType char
int top_S1 = -1;   
  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值