leetcode之二叉树类之二叉树遍历系列-----94/144/145/102/107/103

来源:互联网 发布:mac涂层脱落截止日期 编辑:程序博客网 时间:2024/05/24 07:03

包括:二叉树非递归的按先序、中序、后序的遍历、从上到下按层遍历、从下到上按层遍历、蛇形(ZIGZAG)按层遍历

典型的DFS按栈,BFS按队列的方式:



1、OJ144非递归先序遍历:

root节点先进栈,然后不断弹栈,弹出就输出,同时依次将其右子节点、左子节点(如果存在的话)进栈,直到栈为空

OJ144代码:

class Solution {public:    vector<int> preorderTraversal(TreeNode* root) {        vector<int> res;        if (!root) {            return res;        }                stack<TreeNode *> stk;        stk.push(root);        while (!stk.empty()) {            TreeNode *cur = stk.top();            stk.pop();            res.push_back(cur->val);            if (cur->right) {                stk.push(cur->right);            }            if (cur->left) {                stk.push(cur->left);            }        }                return res;    }};


2、OJ94非递归中序遍历
初始栈为空,任何节点不要入栈,不停的插入左子节点直到最左的leaf节点,弹出并输出,然后改为插入右子节点

OJ94代码:

class Solution {public:    vector<int> inorderTraversal(TreeNode* root) {        vector<int> res;        if (!root) {            return res;        }                stack<TreeNode *> stk;        while (!stk.empty() || root) {            if (root) {                stk.push(root);                root = root->left;            } else {                TreeNode *cur = stk.top();                stk.pop();                res.push_back(cur->val);                root = cur->right;            }        }                return res;    }};

3、OJ145非递归后序遍历

非递归后序遍历的方法比较巧,使用2个栈;

栈1初始压入root,栈2为空,然后步骤为:

1、每次从栈1pop出一个节点,压入栈2,并把这个节点的左子节点、右子节点(如果存在的话),依次压入栈1

2、周而复始做步骤1,直到栈1不再有节点

3、把栈2的节点依次pop出来就是后序遍历

OJ145代码:

class Solution {public:    vector<int> postorderTraversal(TreeNode* root) {        vector<int> res;        if (!root) {            return res;        }                stack<TreeNode *> stk1, stk2;        stk1.push(root);                while (!stk1.empty()) {            TreeNode *cur = stk1.top();            stk1.pop();            stk2.push(cur);                        if (cur->left) {                stk1.push(cur->left);            }            if (cur->right) {                stk1.push(cur->right);            }        }                while (!stk2.empty()) {            res.push_back(stk2.top()->val);            stk2.pop();        }                return res;    }};

4、OJ102从上到下按层遍历

BFS使用queue

OJ102代码:

class Solution {public:    vector<vector<int>> levelOrder(TreeNode* root) {        vector<vector<int>> res;        if (!root) {            return res;        }                queue<TreeNode *> q;        q.push(root);        while (!q.empty()) {            queue<TreeNode *> tmp = q;            vector<int> v;            while (!tmp.empty()) {                v.push_back(tmp.front()->val);                tmp.pop();            }            if (!v.empty()) {                res.push_back(v);            }                        while (!q.empty()) {                TreeNode *cur = q.front();                q.pop();                if (cur->left) {                    tmp.push(cur->left);                }                if (cur->right) {                    tmp.push(cur->right);                }            }            q = tmp;        }                return res;    }};



5、OJ107从下到上按层遍历

加入这一个操作,每层遍历完后用栈保存该层遍历的结果,除此以外和OJ102完全相同

OJ107代码:

class Solution {public:    vector<vector<int>> levelOrderBottom(TreeNode* root) {        vector<vector<int>> res;        if (!root) {            return res;        }                queue<TreeNode *> q;        q.push(root);        stack<vector<int>> stk;                while (!q.empty()) {            queue<TreeNode *> tmp = q;            vector<int> v;            while (!q.empty()) {                TreeNode *cur = q.front();                q.pop();                v.push_back(cur->val);            }            stk.push(v);            while (!tmp.empty()) {                TreeNode *cur = tmp.front();                tmp.pop();                if (cur->left) {                    q.push(cur->left);                }                if (cur->right) {                    q.push(cur->right);                }            }        }                while (!stk.empty()) {            res.push_back(stk.top());            stk.pop();        }        return res;    }};

6、OJ103蛇形(ZIGZAG)遍历:

栈和队列配合使用,队列依然保存每层要输出的节点,但同时用栈也记录当前层节点,然后下一层时反序;

初始时压入root到队列

1、每次遍历队列并输出,同时用栈依次压入每个节点;

2、用一个标志位标识下一层是从右到左还是从左到右,比如下一层是从右到左,当前层的队列肯定是从左到右,那么入栈顺序就是左在栈底右在栈顶,那么遍历栈,并且按先右子节点再左子节点的优先顺序入队列;如果下一层是从左到右,那么当前层空洞是从右到左,所以入队列的优先顺序也要反过来

3、直到队列里不再有元素为止

OJ103代码:

class Solution {public:    vector<vector<int>> zigzagLevelOrder(TreeNode* root) {        vector<vector<int>> res;        if (!root) {            return res;        }                bool flag = false;        stack<TreeNode *> stk;        queue<TreeNode *> q;        q.push(root);        while (!q.empty()) {            vector<int> v;            while (!q.empty()) {                TreeNode *cur = q.front();                q.pop();                v.push_back(cur->val);                stk.push(cur);            }            res.push_back(v);                        if (!flag) {                while (!stk.empty()) {                    TreeNode *cur = stk.top();                    stk.pop();                    if (cur->right) {                        q.push(cur->right);                    }                    if (cur->left) {                        q.push(cur->left);                    }                }            } else {                while (!stk.empty()) {                    TreeNode *cur = stk.top();                    stk.pop();                    if (cur->left) {                        q.push(cur->left);                    }                    if (cur->right) {                        q.push(cur->right);                    }                }            }                        flag = flag?false:true;        }                return res;    }};


原创粉丝点击