递归、迭代分别实现二叉数的三种遍历(前序、中序、后序)

1、建树

2、前序遍历

2.1递归方式实现

2.2迭代方式实现(利用栈)

3、后序遍历

3.1递归方式实现

3.2迭代方式实现(利用前序遍历)

4、中序遍历

4.1递归方式实现

4.2迭代方式实现

 题目练习LeetCode


1、建树

#include <iostream>
#include <vector>
#include <stack>
using namespace std;

//树节点
struct TreeNode{
  int val;
  TreeNode *left;//左孩子
  TreeNode *right;//右孩子
  TreeNode() :left(nullptr), right(nullptr) {}  
};

//已单个节点插入的形式建立二叉搜索树
TreeNode* CreateTreeNode(TreeNode* node, int num){
    //创建根节点
    if(node == nullptr)
    {
        node = new TreeNode();
        node->val = num;
        return node;
    }
    if(num < node->val)
        node->left = CreateTreeNode(node->left, num);
    else if(num > node->val)
        node->right = CreateTreeNode(node->right,num);

    return node;
}

int main(){
    vector<int>nums = {5,3,2,8,9,6,1,7};
	TreeNode* node = nullptr;
	for (int i = 0; i < nums.size(); i++)//建树
	{
		node = CreateTreeNode(node,nums[i]);
	}

    return 0;
}

 

2、前序遍历

前序遍历是访问根节点后,先对其左子树进行遍历后对其右子树进行遍历的一种遍历方式。

俗称:根左右

对图上二叉树遍历结果:{5,3,2,1,8,6,7,9}

2.1递归方式实现

void getDlr(vector<int>& ret, TreeNode* root){
    TreeNode* p = root;
    if(p)
    {
        ret.push_back(p->val);//根节点输出
        getDlr(ret,p->left);//遍历左子树
        getDlr(ret,p->right);//遍历右子树
    }
}
    //统一接口
vector<int> preorderTraversal(TreeNode* root) {
    vector<int> ret;
    getDlr(ret,root);
    return ret;
}

2.2迭代方式实现(利用栈)

vector<int> preorderTraversal(TreeNode* root) {
    vector<int> ret;
    TreeNode *p = root;
    stack<TreeNode*> stk;
    stk.push(p);
    while(!stk.empty())
    {
        p = stk.top();
        if(p == NULL)continue;
        ret.push_back(p->val);//根节点输出
        stk.push(p->right);//右孩子入栈
        stk.push(p->left);//左孩子入栈
    }
    return ret;
}

由于栈为先入后出的数据结构,故先将右子树入栈,后将左子树入栈

3、后序遍历

后序遍历是先对其左子树进行遍历后对其右子树进行遍历,直到左右子树都遍历完毕才访问根节点的一种遍历方式。

俗称:左右根

对图上二叉树遍历结果:{1,2,3,7,6,9,8,5}

3.1递归方式实现

void getLrd(vector<int>& ret, TreeNode* root){
    if(root == NULL)return;
    TreeNode* p = root;
    getLrd(ret,p->left);//左
    getLrd(ret,p->right);//右
    ret.push_back(p->val);//根
}
vector<int> postorderTraversal(TreeNode* root) {
    vector<int> ret;
    getLrd(ret,root);
    return ret;
}

3.2迭代方式实现(利用前序遍历)

vector<int> postorderTraversal(TreeNode* root) {
    vector<int> ret;
    TreeNode *p = root;
    stack<TreeNode*> stk;
    stk.push(p);
    while(!stk.empty())
    {
        p = stk.top();
        stk.pop();
        if(p == NULL)continue;
        ret.push_back(p->val);//根
        stk.push(p->left);//左
        stk.push(p->right);//右
    }
    //翻转
    reverse(ret.begin(),ret.end());
    return ret;
}

前序遍历的输出顺序为根左右,而后序遍历的输出顺序为左右根,我们只需调整一下前序遍历,将其变成根右左,然后翻转一下输出数组,即变成了左右根。

4、中序遍历

中序遍历是先对其左子树进行遍历后,左子树遍历完后访问根节点,然后对对其右子树进行遍历的遍历方式。

俗称:左根右

对图上二叉树遍历结果:{1,2,3,5,6,7,8,9}

4.1递归方式实现

void getLdr(vector<int>& ret, TreeNode* root){
    if(root == NULL)return;
    TreeNode* p = root;
    getLdr(ret,p->left);//左
    ret.push_back(p->val);//根
    getLdr(ret,p->right);//右
}
vector<int> inorderTraversal(TreeNode* root) {
    vector<int>ret;
    getLdr(ret,root);
    return ret;
}

4.2迭代方式实现

vector<int> inorderTraversal(TreeNode* root) {
    stack<TreeNode*>stk;
    vector<int>ret;
    TreeNode* now = root;
    while(now || !stk.empty())
    {
        while(now)//遍历完左子树
        {
            stk.push(now);
            now = now->left;
        }
        ret.push_back(stk.top()->val);//访问根节点
        now = stk.top()->right;//访问右子树
        stk.pop();
    }
    return ret;
}

 题目练习LeetCode

144. 二叉树的前序遍历

145. 二叉树的后序遍历

94. 二叉树的中序遍历

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值