zoukankan      html  css  js  c++  java
  • 二叉树遍历

    二叉树遍历

      依据根节点的访问次序分为先序遍历、中序遍历、后序遍历、层序遍历。中序遍历即以左节点、根节点、右节点的顺序遍历,根节点放在中间,其它方式依此类推。下面介绍三种中序遍历算法。

    递归

      递归法简单明了,但是效率较低。下面为中序遍历,前序遍历和后序遍历同理。

    /**
     * Definition for a binary tree node.
     * struct TreeNode {
     *     int val;
     *     TreeNode *left;
     *     TreeNode *right;
     *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
     * };
     */
    
    void inorderTraversal(TreeNode* root, vector<int>& list){
        if(root != NULL){
            inorderTraversal(root->left, list);
            list.push_back(root->val);
            inorderTraversal(root->right, list);
        }
    }

    栈方法

    • 前序遍历

    vector<int> inorderTraversal(TreeNode* root) {
         vector<int> res;
            vector<TreeNode*> stk;
            TreeNode* cur = root;
            while(cur != NULL || stk.size() != 0){
                if(cur != NULL) {
                    res.push_back(cur->val);
                    stk.push_back(cur);
                    cur = cur->left;
                }
                else {
                    cur = stk.back();
                    stk.pop_back();
                    cur = cur->right;
                }
            }
            return res;
    }
    • 中序遍历

    vector<int> inorderTraversal(TreeNode* root) {
          vector<int> res;
            vector<TreeNode*> stk;
            TreeNode* cur = root;
            while(cur != NULL || stk.size() != 0){
                if(cur != NULL) {
                    stk.push_back(cur);
                    cur = cur->left;
                }
                else {
                    cur = stk.back();
                    res.push_back(cur->val);
                    stk.pop_back();
                    cur = cur->right;
                }
            }
            return res;
    }                        
    • 后续遍历

    vector<int> postorderTraversal(TreeNode* root) {
            vector<int> res;
            if(root == NULL) return res;
            stack<TreeNode*> tree;
            while(root != NULL || tree.size() != 0) {
                if(root != NULL) {
                    tree.push(root);
                    res.insert(res.begin(), root->val); //因为是后续遍历,节点需要从队头插入,并且先遍历右子树,加入的顺序是中-右-左,这样最终的顺序就是左-右-中
                    root = root->right;
                }
                else {
                    root = tree.top()->left;
                    tree.pop();
                }
            }
            return res;
        }

    莫里斯遍历

      该方法通过设置根节点作为其前驱节点的右孩子,来构造线索二叉树,这样在遍历完左子树时,遍历前驱结点的右孩子就可以跳转到根节点继续遍历右子树。下面是中序遍历实现,前序遍历通过更改res.push_back()的位置即可,后续遍历可以用上述思想,将前序遍历修改为头部插入,并且先遍历右子树。

    vector<int> inorderTraversal(TreeNode* root) {
            vector<int> res;
            TreeNode* pre;
            while(root){
                if(root->left){
                    pre = root->left;
                    while(pre->right && pre->right != root) pre = pre->right;
                    if(pre->right == NULL){  //说明root第一次作为当前根节点出现,其左子树没有遍历过,则为其前驱结点设置线索,进入左子树。
                        pre->right = root;
                        root = root->left;
                        continue;
                    }
              //说明root是通过前驱结点->right跳转到的,左子树已经遍历完成,需要删除线索,进入右子树。 pre
    ->right = NULL; res.push_back(root->val); root = root->right; } else{ res.push_back(root->val); root = root->right; } } return res; }
  • 相关阅读:
    The XOR Largest Pair
    似乎在梦中见过的样子 (KMP)
    Censoring(栈+KMP)
    KMP解决最小循环节问题
    收集雪花 (贪心+双指针+离散化)
    「POI2010」反对称 Antisymmetry (manacher算法)
    A Horrible Poem (字符串hash+数论)
    leetcode103——二叉树的锯齿形层次遍历
    leetcode102 ——二叉树的层序遍历
    二叉树——100 相同的树(easy)
  • 原文地址:https://www.cnblogs.com/zz-zhang/p/inorderTraversal.html
Copyright © 2011-2022 走看看