遍历二叉树的迭代和递归方法

二叉树的问题,一定要明白到底应该深度优先(前中后序)还是广度优先(层序遍历)

最基本的遍历方式:深度优先和广度优先

  深度优先:前、中、后序(递归法和迭代法均可)

  广度优先:层次遍历(迭代法)

栈其实就是递归的一种实现结构,也就是说前中后序遍历的逻辑其实都是可以借助栈使用非递归的方式来实现的;

广度优先遍历(层序遍历)的实现一般使用队列来实现,这也是队列先进先出的特点所决定的,因为需要先进先出的结构,才能一层一层的来遍历二叉树。

二叉树节点的定义框架:

复制代码

struct TreeNode {

    int val;

    TreeNode *left;

    TreeNode *right;

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

};

复制代码

二叉树的递归遍历框架:

复制代码

/*二叉树的遍历框架*/

void traverse(TreeNode root)

{

    //前序遍历:先访问根节点,再前序访问左子树,再访问右子树

    traverse(root->left);

    //中序遍历:先中序访问左子树,再访问根节点,再访问右子树

    traverse(root->right);

    //后续遍历:先后续访问左子树,再访问右子树,再访问根节点

}

复制代码

一、二叉树的前序遍历:迭代和递归

复制代码

class Solution {

public:

    //vector<int> result;//递归的话定义在这里

    vector<int> preorderTraversal(TreeNode* root) {

        //递归方式

        /*

        if(root == nullptr)

            return {};

        result.push_back(root->val);

        preorderTraversal(root->left);

        preorderTraversal(root->right);

        return result;

        */

        //当然可以使用迭代解法,因为递归本身就是用栈来实现的,可以通过栈来迭代操作

        //但是要注意栈的特性是后入先出,前序的话,就是先放入根节点赋值操作弹出,再放入右节点、左节点,再弹出,这样左节点就会先出,先赋值操作,就是前序了

        stack<TreeNode*> sta;

        vector<int> result;

        sta.push(root);

        while(!sta.empty()) {

            int size = sta.size();

            for(int i=0; i<size; i++) {

                TreeNode* node = sta.top();

                sta.pop();

                result.push_back(node->val);

                if(node->right)

                    sta.push(node->right);

                if(node->left)

                    sta.push(node->left);

            }

        }

        return result;

    }

};

复制代码

二、二叉树的后序遍历:迭代和递归

复制代码

/**

* Definition for a binary tree node.

* struct TreeNode {

*    int val;

*    TreeNode *left;

*    TreeNode *right;

*    TreeNode() : val(0), left(nullptr), right(nullptr) {}

*    TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}

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

* };

*/

class Solution {

public:

    //vector<int> result;//递归解法定义在这里

    vector<int> postorderTraversal(TreeNode* root) {

        /*

        if(root == nullptr)

            return {};

        postorderTraversal(root->left);

        postorderTraversal(root->right);

        result.push_back(root->val);

        return result;

        */

        //本题还可以采用迭代解法,因为递归就是用栈来实现的

        //考虑实现的过程

        //后序遍历是左右中的顺序,但是我们在迭代的时候肯定会先访问根节点,也就是中间的节点,所以考虑先访问和处理中间节点,再处理右节点,再处理左边节点,最后将结果翻转就行了

        stack<TreeNode*> sta;

        vector<int> result;

        sta.push(root);

        while(!sta.empty()) {

            int size = sta.size();

            for(int i=0; i<size; i++) {

                TreeNode* node = sta.top();

                sta.pop();

                result.push_back(node->val);

                if(node->left)

                    sta.push(node->left);

                if(node->right)

                    sta.push(node->right);

            }

        }

        reverse(result.begin(), result.end());

        return result;

    }

};

复制代码

三、二叉树的中序遍历:迭代和递归

复制代码

/**

* Definition for a binary tree node.

* struct TreeNode {

*    int val;

*    TreeNode *left;

*    TreeNode *right;

*    TreeNode() : val(0), left(nullptr), right(nullptr) {}

*    TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}

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

* };

*/

class Solution {

public:

    //vector<int>result;//递归写法这里定义

    vector<int> inorderTraversal(TreeNode* root) {

        /*递归解法

        if(root == nullptr)

            return {};

        inorderTraversal(root->left);

        result.push_back(root->val);

        inorderTraversal(root->right);

        return result;

        */

        //还能采用迭代解法,用栈来解决,因为递归本身就是用栈来实现的,因此是完全行得通的

        //中序的顺序是左中右,那出栈的时候,处理的顺序肯定是右中左

        //搞清楚访问和处理的概念

        //访问:将节点入栈

        //处理:将节点的值放入结果集

        //中序的访问和处理的顺序是不一样的,所以要借助指针进行访问,也就是将节点放入栈中,用栈来做处理,也就是放入结果集

        vector<int> result;

        stack<TreeNode*> sta;

        TreeNode* cur = root;

        while(cur != nullptr || !sta.empty()) {

            if(cur != nullptr) {//指针用来访问节点,访问到左边最底层的时候,指针和要开始处理的位置就一样了

                sta.push(cur);//将访问的节点放进栈

                cur = cur->left;//最左的子节点最后放进去,所以会先出栈    左

            }

            else {

                cur = sta.top();

                sta.pop();

                result.push_back(cur->val);                            //中

                cur = cur->right;                                      //右

            }

        }

    }

};

复制代码

四、二叉树的层序遍历:迭代和递归

复制代码

/**

* Definition for a binary tree node.

* struct TreeNode {

*    int val;

*    TreeNode *left;

*    TreeNode *right;

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

* };

*/

class Solution {

public:

    vector<vector<int>> levelOrder(TreeNode* root) {

        queue<TreeNode*> que;//创建一个队列,层序遍历树的需要用队列来实现,队列中是二叉树的节点

        if(root != nullptr)

            que.push(root);//如果头结点不为空的话,先将头结点放到队列中,因为头结点也就是第一行,只有这一个元素,所以直接放进去

        vector<vector<int>> result;//定义返回值,返回的是一个二维数组

        while(!que.empty()) {

            int size = que.size();//同一行可能不止一个元素,要循环都进行遍历,又因为下面要进行pop操作,que.size()是一个变化的值,所以这里存储数量

            vector<int> vec;//用于临时存储每一行的节点值,最后统一存入返回的二维数组中

            for(int i=0; i<size; i++) {

                TreeNode* node = que.front();

                que.pop();//

                vec.push_back(node->val);

                if(node->left)

                    que.push(node->left);//将这个节点的左右子节点放入队列中

                if(node->right)

                    que.push(node->right);

            }

            result.push_back(vec);

        }

        return result;

    }

};

复制代码

深圳网站建设www.sz886.com

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,332评论 5 475
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,930评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,204评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,348评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,356评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,447评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,862评论 3 394
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,516评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,710评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,518评论 2 318
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,582评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,295评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,848评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,881评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,121评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,737评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,280评论 2 341

推荐阅读更多精彩内容