算法 二叉树 【中序遍历迭代版】

41 篇文章 1 订阅
4 篇文章 0 订阅

目录

一、思路

二、举例

三、代码


一、思路

迭代法需要借助while循环和迭代栈。

中序遍历的顺序:左-根-右

遍历步骤:

1.准备一个当前指针cur,指向根结点;

2.开辟一个空的迭代栈;

3.进入while循环。循环结束的条件是:当前指针为空并且迭代栈为空。

        因为当前指针不为空,迭代栈为空的情况是:根结点还未入栈

        当前指针为空,迭代栈不为空的情况是:当前指针指向了目前最左元素的左孩子,而这个孩子肯定是nullptr

4.在大循环中,首先建立一个小循环,不断地将当前指针指向的结点入栈,然后当前指针指向这个结点的左孩子;

5.由于4中,当前指针肯定最终指向空,所以让当前指针指向栈顶元素,此时栈顶元素即为应该遍历的元素;

6.栈顶元素入结果集后,出栈,再让其右孩子入栈,因为肯定已经遍历完成了当前子树的左和根;

7.重复上述操作

 

二、举例

假设有这样一颗树:

1.根结点入栈

2.不断让左孩子入栈

3.弹出栈顶元素,让其右孩子入栈

4.重复上述操作,直到当前指针为空且栈为空

 

 

三、代码

核心代码:

vector<int> inorderTraversal(TreeNode* root) 
{
    vector<int> ans;
    stack<TreeNode*> s;
    TreeNode* cur = root;
    //当前结点不为空或者栈不为空
    //也就是说,循环结束条件是:
    //当前结点为空且栈为空
    while (cur != nullptr || !s.empty())
    {
        //如果当前结点不为空,那么就放入栈,
        //然后当前指针指向其左孩子结点
        if (cur != nullptr)
        {
            s.push(cur);
            cur = cur->left;
        }
        //如果当前结点为空,说明已经到目前最左的尽头,
        //那么指向栈顶元素
        //此时的栈顶元素为以当前结点为根的子树的根
        //其左孩子因为已经为空,所以目前遍历根
        //遍历完后再让当前指针指向其右孩子结点
        else
        {
            cur = s.top();
            s.pop();
            ans.push_back(cur->val);
            cur = cur->right;
        }
    }
    return ans;
}

测试用例:

int main()
{
    TreeNode* root = (TreeNode*)malloc(sizeof(TreeNode));
    root->val = 3;
    TreeNode* n1 = (TreeNode*)malloc(sizeof(TreeNode));
    n1->val = 4;
    TreeNode* n2 = (TreeNode*)malloc(sizeof(TreeNode));
    n2->val = 5;
    TreeNode* n3 = (TreeNode*)malloc(sizeof(TreeNode));
    n3->val = 6;
    TreeNode* n4 = (TreeNode*)malloc(sizeof(TreeNode));
    n4->val = 7;
    TreeNode* n5 = (TreeNode*)malloc(sizeof(TreeNode));
    n5->val = 8;
    TreeNode* n6 = (TreeNode*)malloc(sizeof(TreeNode));
    n6->val = 9;
    root->left = n1;
    root->right = n2;
    n1->left = n3;
    n1->right = n4;
    n2->left = n5;
    n2->right = n6;
    n3->left = nullptr;
    n3->right = nullptr;
    n4->left = nullptr;
    n4->right = nullptr;
    n5->left = nullptr;
    n5->right = nullptr;
    n6->left = nullptr;
    n6->right = nullptr;
    vector<int> v = inorderTraversal(root);
    for (int i = 0; i < v.size(); i++)
    {
        cout << v[i] << " ";
    }
	return 0;
}

运行截图:

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值