二叉树的遍历:前序、中序、后续(递归+迭代)

本文介绍了二叉树的前序、中序和后序遍历的递归与迭代两种方法。递归法直观简洁,而迭代法则通过模拟栈操作实现。在迭代法中,先序遍历需先检查右节点再左节点,后序遍历通过调整左右节点入栈顺序并反转结果数组来得到正确顺序。中序遍历则从左至右遍历直到找到最左节点,然后返回并转向右节点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

         今天学会了二叉树的三种遍历方式,根据自己的个人理解记录下来。



力扣144:二叉树的前序遍历

力扣94:二叉树的中序遍历

力扣145:二叉树的后续遍历

首先是最简单的递归法:

//先序
void ret1(struct TreeNode* root, int* returnSize,int* ans){
    if(root==NULL)
        return;
     ans[(*returnSize)++]=root->val;
    ret(root->left, returnSize,ans);
    ret(root->right, returnSize,ans);
}

//中序
void ret2(struct TreeNode* root, int* returnSize,int* ans){
    if(root==NULL)
        return;
    ret(root->left, returnSize,ans);
    ans[(*returnSize)++]=root->val;
    ret(root->right, returnSize,ans);
}

//后序
void ret3(struct TreeNode* root, int* returnSize,int* ans){
    if(root==NULL)
        return;
    ret(root->left, returnSize,ans);
    ret(root->right, returnSize,ans);
    ans[(*returnSize)++]=root->val;
}



int* postorderTraversal(struct TreeNode* root, int* returnSize){
    int* ans=(int*)malloc(sizeof(int)*100);
    *returnSize=0;
    ret1(root, returnSize,ans);
    return ans;
}

递归的思路非常简单:调用自己+终止条件

迭代法:

        迭代法的思路是通过模拟栈的方式达到递归调用的效果,但三种遍历方式的遍历操作大不相同。

先序:

        0、初始设置:将根结点入栈

        1、弹出栈顶结点,并将其数据输出

        2、若此结点右节点不为空则入栈

        3、若此结点左结点不为空则入栈

        4、当栈空时退出循环

注意:这里需要先检查右结点,后检查左节点,以便弹出时先弹出左节点。

int* preorderTraversal(struct TreeNode* root, int* returnSize){
    int* ans=(int*)malloc(sizeof(int)*100);
    *returnSize=0;
    struct TreeNode* stack[100];
    if(root==NULL)
        return ans;
    int top=0;
    stack[0]=root;   //将根节点入栈
    while(top!=-1){  //当栈不为空
        struct TreeNode* node=stack[top--];//将栈顶结点弹出为当前结点

        ans[(*returnSize)++]=node->val;  //将当前结点数值输出(存入ans数组)
        
        if(node->right!=NULL)    //如果右子树不为空则入栈
            stack[++top]=node->right;

        if(node->left!=NULL)     //如果左子树不为空则出栈
            stack[++top]=node->left;  
    }
    return ans;
}

后序:

        0、将根节点入栈

        1、弹出栈顶结点作为当前结点,并将数据输出

        2、如果左节点不空则入栈

        3、如果右节点不空则入栈

        4、当栈空时退出循环

        5、将答案数组翻转

注意:这里用了一个取巧的方法将先序的代码中左右结点入栈的顺序颠倒,先序的遍历顺序为头->左->右,颠倒后就变成了头->右->左。最后将答案数组颠倒变成左->右->头即可。

所以虽然最终的答案正确,但实际上并没有按照左->右->头的顺序遍历。

int* postorderTraversal(struct TreeNode* root, int* returnSize){
    int* ans=(int*)malloc(sizeof(int)*100);
    *returnSize=0;
    if(root==NULL)
        return ans;
    struct TreeNode* stack[100];
    int top=0;
    stack[top]=root;//将根节点入栈

    while(top!=-1){//当栈不为空时
        struct TreeNode* node=stack[top--];//将栈顶结点弹出作为当前结点
        ans[(*returnSize)++]=node->val;//将当前结点数据输出

        if(node->left)//如果左节点不空则入栈
            stack[++top]=node->left;

        if(node->right)//如果右节点不空则入栈
            stack[++top]=node->right;
    }

    int i=0,j=*returnSize-1;//将ans数组翻转
    while(i<j){
        int temp=ans[i];
        ans[i++]=ans[j];
        ans[j--]=temp;
    }
    return ans;
}

中序:

        0、将根节点作为当前结点

        1、if 当前结点不为空时入栈,当前结点继续向左走一步

        2、else 弹出栈顶结点成为当前结点并输出,当前结点向右走一一步

        3、栈空且当前结点为空时退出循环

int* inorderTraversal(struct TreeNode* root, int* returnSize){
    int* ans=(int*)malloc(sizeof(int)*100);
    *returnSize=0;
    if(root==NULL)
        return ans;
    struct TreeNode* stack[100];
    int top=-1;
    struct TreeNode* node=root; //将根节点作为当前结点

    while(top>-1||node!=NULL){  //当栈不为空或当前结点不为空时
        if(node!=NULL){   //如果当前结点不为空则入栈
            stack[++top]=node;
            node=node->left; //当前结点继续向左
        }

        else{  //如果当前结点为空,说明向左走到头了
            node=stack[top--];//弹出栈顶结点成为当前结点并输出
            ans[(*returnSize)++]=node->val;
            node=node->right;//当前结点继续向右
        }
    }
    return ans;
}

中序遍历的大致思路为:先一直向左走到最左结点,然后向上返回一步,然后向右走一步,然后不断循环。

这就是我对于二叉树遍历的理解,如有错误欢迎指正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值