二叉树遍历

冷暖自知 提交于 2020-03-09 18:17:40

两种遍历树的策略:

深度优先搜索(DFS)

在这个策略中,我们采用深度作为优先级,以便从跟开始一直到达某个确定的叶子,然后再返回根到达另一个分支。

方法一、递归

深度优先搜索策略又可以根据根节点、左孩子和右孩子的相对顺序被细分为前序遍历,中序遍历和后序遍历。

  1. 前序遍历:根->左->右
  2. 中序遍历:左->根->右
  3. 后序遍历:左->右->根
res.push_back(root->val);//打印根节点
helper(root->left);
helper(root->right);

迭代

深度优秀遍历用递归求解非常简单,难的是迭代方法:

前序遍历

首先我们应该创建一个Stack用来存放节点,首先我们想要打印根节点的数据,此时Stack里面的内容为空,所以我们优先将头结点加入Stack,然后打印。

之后我们应该先打印左子树,然后右子树。所以先加入Stack的就是右子树,然后左子树。
此时你能得到的流程如下:
在这里插入图片 描述

 vector<int> preorderTraversal(TreeNode* root) {
        vector<int> res;
        if(!root)return {};       
        stack<TreeNode*> s;
    
        TreeNode *tmp=root;
        
        while(tmp || !s.empty()){
            if(tmp){
                s.push(tmp);
                res.push_back(tmp->val);
                tmp=tmp->left;
            }else{
                tmp=s.top();
                s.pop();
                tmp=tmp->right;
            }
        }
       return res;      
    } 

使用stack作为辅助存储。
第一次遇到的节点,首先visit,再将其放进栈当中,按照前序遍历的规则继续往该节点的左子树遍历直到左子树为空。
接着pop出栈顶元素该节点必然是访问顺序当中的上一个节点,此时该节点是第二次访问到,直接出栈。
此时cur的左子树以及自己已经都被visit过了,此时应往cur的右子树遍历。
循环往复执行以上的步骤,直到栈为空

中序遍历

递归的调用过程是不断往左边走,当左边走不下去了,就打印节点,并转向右边,然后右边继续这个过程。
我们在迭代实现时,就可以用栈来模拟上面的调用过程。

    vector<int> inorderTraversal(TreeNode *root) {
        vector<int> res;
        stack<TreeNode*> s;
        TreeNode *cur=root;
        
        while(cur || !s.empty()){
            if(cur){
                s.push(cur);
                cur=cur->left;//判断是否有值并向左侧寻找
            }else{
                cur=s.top();
                s.pop();
                res.push_back(cur->val);
                cur=cur->right;//当左侧为空时,遍历右侧
            }
        }
        return res;
    }

对于二叉树的遍历有一个结论:三种遍历顺序的遍历路径是一样的,只是前序遍历在第一次遇到节点的时候就访问,中序遍历则是第二次访问到该节点的时候进行访问,后序遍历则是第三次访问到该节点才进行实际的访问。
所以中序遍历区别于前序遍历的唯一区别就是实际访问的顺序,把节点放入栈的过程是第一次访问到,将节点pop出栈的时候对该节点是第二次访问,按照相同的访问顺序此时是中序遍历应该实际访问的时候。所以只需要改变访问的位置即可。

后序遍历

stack<TempNode *> s;
    TreeNode *p = root;
    TempNode *temp;
    while(p != NULL || !s.empty())
    {
        while(p != NULL) //沿左子树一直往下搜索,直至出现没有左子树的结点
        {
            TreeNode *tempNode = new TreeNode;
            tempNode->btnode = p;
            tempNode->isFirst = true;
            s.push(tempNode);
            p = p->left;
        }
        if(!s.empty())
        {
            temp = s.top();
            s.pop();
            if(temp->isFirst == true)   //表示是第一次出现在栈顶
            {
                temp->isFirst = false;
                s.push(temp);
                p = temp->btnode->right;
            }
            else  //第二次出现在栈顶
            {
                path.push_back(temp->btnode->val);
                p = NULL;
            }
        }
    }

宽度优先搜索(BFS)

我们按照高度顺序一层一层的访问整棵树,高层次的节点将会比低层次的节点先被访问到。如:层次遍历(基于辅助队列)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!