【C++】【二叉树】二叉树的前、中、后序遍历;迭代、染色法、颜色标记法;

本文介绍了二叉树遍历的一种创新方法——颜色标记法,通过使用节点颜色状态来辅助遍历。这种方法适用于前序、中序和后序遍历,通过改变入栈顺序实现不同遍历。在后序遍历中,从根节点开始,按照右、左、中顺序入栈,利用栈的特性完成节点处理。理解这种方法的关键在于掌握入栈顺序和节点状态的转换,而不是依赖固定的模板。
摘要由CSDN通过智能技术生成


前言

又看了二叉树的遍历的时候,看到了一个大佬的颜色标记法。原文在下面引用处。

觉得很有意思,很多经典的迭代方法也是出于这种方法来的。

但是颜色标记法,就很容易突破障碍,清晰易懂。

一、颜色标记法

核心思想如下:

  1. 使用颜色标记节点的状态,新节点为白色,已访问的节点为灰色。
  2. 如果遇到的节点为白色,则将其标记为灰色,然后将其右子节点、自身、左子节点依次入栈。
  3. 如果遇到的节点为灰色,则将节点的值输出。

其实只需要一个bool值即可,false 代表没经过过这个节点,true 表示已经经过过了,可以处理了。

实现如下:


   vector<int> postorderTraversal(TreeNode* root) {
       vector<int> result;
       stack<pair<TreeNode*,bool>> stck_tree;
       stck_tree.push(make_pair(root,false));
       while(!stck_tree.empty())
       {
           auto [cur,passed] = stck_tree.top();
           stck_tree.pop();
           if(cur == nullptr) continue;
           if(passed ==false)
           {
               
               stck_tree.push(make_pair(cur->right,false));//前序遍历
               stck_tree.push(make_pair(cur->left,false));
               stck_tree.push(make_pair(cur,true));

               stck_tree.push(make_pair(cur->right,false));//中序遍历
               stck_tree.push(make_pair(cur,true));
               stck_tree.push(make_pair(cur->left,false));

               stck_tree.push(make_pair(cur,true));        //后序遍历
               stck_tree.push(make_pair(cur->right,false));
               stck_tree.push(make_pair(cur->left,false));
           }
           else
               result.push_back(cur->val);
       }
       return result;
   }

其中if语句中,三段是三种遍历不同的地方。仅此而已。

是不是简单易懂。

其实并不是要套模板,需要理解了以后随时都能写的出来。而不是死记住模板

二、加强理解

1.入栈顺序

入栈顺序根据遍历的顺序的倒序来即可。

栈是一种 先进后出的结构

所以需要前序 中 左 右做处理的话,就需要 右、左、中 入栈。

这样造成一个节点会两次入栈,也正是利用这种性质来记录了节点处理的顺序。

2. 理解

拿后序遍历来讲。

  1. 首先从根部开始 root、 right、 left 顺序入栈;
  2. 弹出left ,将其改变标记为true,再次入栈,同时将其right 、left入栈;
  3. 一直到最左边的节点,将其入栈后,子树都因为是null 而弹出,最终是其本身开始操作。
  4. 然后因为其父节点按照root、 right、 left 顺序入栈;本left节点处理完了,再弹出就是right节点的操作了。最后才是root 节点的操作。
  5. 这样就完成了后序遍历的处理。

这样画一个二叉树,理解一下。

会发现其实就是利用栈的性质,按顺序记录后面要处理的节点。

很多后序遍历的迭代方法,都会用一个pre指针来记录上次处理过的节点,其实也是类似的想法。

三、引用

https://leetcode-cn.com/problems/binary-tree-inorder-traversal/solution/yan-se-biao-ji-fa-yi-chong-tong-yong-qie-jian-ming/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值