有穷状态自动机--一层循环迭代实现二叉树的前中后序遍历(对面试官降维打击)

状态机过程详解

我们定义三个状态:

  1. LEFT状态:代表左右子树均未被遍历
  2. RIGHT状态:代表左子树被遍历
  3. UP状态:代表左右子树都被遍历过

注意还需要一个栈用于存储遍历路径,方便拿取父节点。

  • 实现了这个迭代过程后,我们发现,实际上LEFT状态就是前序遍历的操作状态,RIGHT状态就是中序遍历的操作状态,UP状态就是后序遍历的操作状态,自此用迭代实现了递归的完全模拟!!!

画出状态转移图
image.png

(前序遍历代码)代码

C语言实现:

 //定义三种状态,
 //LEFT状态代表左右子树均未被遍历
 //RIGHT状态代表左子树被遍历
 //UP状态代表左右子树都被遍历过
 //用栈记录遍历路径
 //那么实现前序只需要在LEFT状态下把结点加入答案即可
#define MAXSIZE 100
typedef struct TreeNode TreeNode;
const int LEFT = 1;
const int RIGHT = 2;
const int UP = 3;
int* preorderTraversal(struct TreeNode* root, int* returnSize) {
    TreeNode* path[MAXSIZE];//用栈存储路径
    int* res = (int*)calloc(MAXSIZE, sizeof(int));
    int top = 0;//栈顶指针
    int index = 0;//用于更新res的下标
    int state = LEFT;//开始时在根节点,左右子树均为被遍历
    while (root != NULL) { //三种不同情况的路径处理
        if (state == LEFT) {
            //由于此时的root是LEFT状态,也就是左右子树都未遍历过,这个状态正好就是前序所需要处理的状态
            res[index++] = root->val;
            if (root->left != NULL) {
                path[top++] = root;
                root = root->left;
            } else {
                state = RIGHT;//如果左子树为空则进入RIGHT状态
            }
        } else if (state == RIGHT) {
            if (root->right != NULL) {
                state = LEFT;//注意转移状态
                path[top++] = root;
                root = root->right;
            } else {
                state = UP;//如果左右子树均被遍历完,则进入UP状态
            }
        } else if (state == UP) {
            TreeNode* p = NULL;//临时变量用于存储路径双亲结点(如果存在的话)
            if (top != 0) { //栈不为空时,得出路径中的上一个结点(肯定是双亲结点)
                p = path[top - 1]; top--; //出栈
                if (root == p->left) { //如果进入UP状态的结点是它双亲的左子树
                    state = RIGHT;//则进入RIGHT状态,否则仍然是UP状态
                }
            }
            root = p;
        }
    }
    *returnSize = index;
    return res;

}

C++实现:

 //定义三种状态,
 //LEFT状态代表左右子树均未被遍历
 //RIGHT状态代表左子树被遍历
 //UP状态代表左右子树都被遍历过
 //用栈记录遍历路径
 //那么实现前序只需要在LEFT状态下把结点加入答案即可
class Solution { 
const int LEFT = 1;
const int RIGHT =  2;
const int UP = 3;
public:
    vector<int> preorderTraversal(TreeNode* root) {
        vector<int>res;
        vector<TreeNode*>path;
        int state = LEFT;
        while(root){
            if(state == LEFT){
                res.emplace_back(root->val);
                if(root->left){
                    path.emplace_back(root);
                    root = root->left;
                }else
                state = RIGHT;
            }
            else if(state == RIGHT){
                if(root->right){
                    state = LEFT;
                    path.emplace_back(root);
                    root = root->right;
                }
                else state = UP;
            }else if(state == UP){
                TreeNode* p = nullptr;
                if(!path.empty()){
                    p = path.back();path.pop_back();
                    if(root==p->left){
                        state = RIGHT;
                    }
                }
                root = p;
            }
        }
        return res;
    }
};
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值