代码随想录day13|二叉树理论基础、二叉树的递归遍历、二叉树的迭代遍历

二叉树理论基础

这边需要重点注意的是二叉树的链式节点的定义

struct TreeNode(){
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode(int x) : val(x) , left(NULL) , right(NULL){}
};

其中TreeNode(int x) : val(x) , left(NULL) , right(NULL){}是初始化列表的操作。

 二叉树的递归遍历

递归遍历主要保证三要素:

1、确定递归函数的参数和返回值:在我们进行前中后需遍历的时候,我们需要传入二叉树的节点,又由于我们需要打印遍历节点的数值,因此我们也需要传入一个vector容器来存放我们的节点数值。void traversal(TreeNode *cur,vector& vec)

2、确定终止条件:当我们节点为空的时候结束遍历。if(cur == NULL)

3、确定单层递归的逻辑:我们以前序遍历为例子,我们就可以写出vec.push_back(cur->val);

traversal(cur->left,vec),traversal(cur->right,vec)

class Solution {
public:
    void traversal(TreeNode* cur,vector& vec)
    {
        if(cur == NULL) return;
        traversal(cur->left,vec);
        vec.push_back(cur->val);
        traversal(cur->right,vec);
    }
    vector inorderTraversal(TreeNode* root) {
        vector result;
        traversal(root,result);
        return result;
    }
};

二叉树的迭代遍历

对于前序遍历来说,我们不使用递归的方法来遍历二叉树,我们将二叉树的节点都存入栈中,用vector数组来树放节点的数值。

class Solution {
public:
    vector preorderTraversal(TreeNode* root) {
        stack st;//用栈来存储节点
        vector result;//用数组来存储结果数据
        if(root == NULL) return result;
        st.push(root);//把根节点存入栈
        while(!st.empty())
        {
            TreeNode *node = st.top();//用一个指针指向栈的顶端
            st.pop();//弹出最顶端元素
            result.push_back(node->val);
            if(node->right) st.push(node->right);
            if(node->left) st.push(node->left);
        }
        return result;
    }
};

其实后序遍历的思想和前序遍历差不多,前序遍历是中左右,迭代遍历就是中右左。其实我们可以迭代遍历中左右,那么递归遍历就是中右左,最后我们反过来就是左右中,得到的就是后序遍历的结果。 

class Solution {
public:
    vector postorderTraversal(TreeNode* root) {
        stack st;
        vector result;
        if(root == NULL) return result;
        st.push(root);
        while(!st.empty())
        {
            TreeNode* node = st.top();
            st.pop();
            result.push_back(node->val);
            if(node->left) st.push(node->left);
            if(node->right) st.push(node->right);
        }
        reverse(result.begin(),result.end());
        return result;
    }
};

中序遍历和前后序遍历是有些不同,因为中序遍历的时候第一个要处理的节点不是根节点,我们必须先处理最左边的节点,我们用一个cur指针遍历二叉树,我们首先将所有的左节点从根节点开始入栈,当cur指向空时候,我们就弹出的栈顶的元素,并将数值存入数组,这样就处理了中的操作,接下来让cur指向右节点,只要cur为空,就弹出栈中元素,最后当栈中没有元素了,就结束循环,一开始需要加一个cur!=NULL条件,不然从一开始就不进入循环了。

class Solution {
public:
    vector inorderTraversal(TreeNode* root) {
        stack st;
        vector result;
        TreeNode* cur = root;
        while(cur != NULL || !st.empty())
        {
            if(cur != NULL)//cur不为空的时候
            {
                st.push(cur);
                cur = cur->left;           //左
            }
            else//cur为空的时候,这时候需要弹出最外层的元素
            {
                cur = st.top();
                st.pop();
                result.push_back(cur->val);//中
                cur = cur->right;                //右
            }
        }   
        return result;
    }
};

你可能感兴趣的:(算法,c++,数据结构)