二叉树非递归遍历--迭代
来源:互联网 发布:mysql 入侵 编辑:程序博客网 时间:2024/04/27 23:56
无论是何种遍历都抓住遍历的特征
先、中、后,三种遍历方式,都是深度优先搜索,差别仅在于访问根节点的顺序。
深度优先搜索的特点:
1、使用栈。
2、存在可访问节点时,向下延伸。
3、无可访问节点时,回退至上级可访问节点。
二叉树先、中、后遍历中DFS思想的体现:
1、使用栈。
2、左子树存在,向左子树迭代。
3、左子树不存在,移向右子树,回2。
1、先序
特征:一直向左,对访问的节点进行入栈,直到左边没有,回退,向右一步,再回到一直向左。
/** * Definition for binary tree * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */class Solution {public: vector<int> preorderTraversal(TreeNode *root) { stack<TreeNode *> pStack; while (root || !pStack.empty()) { while (root) { result.push_back(root->val); pStack.push(root); root = root->left; } if (!pStack.empty()) { // 这里栈不会为空,所以可以去掉 root = pStack.top(); pStack.pop(); root = root->right; } } return result; }private: vector<int> result;};
2、中序
特征:一直向左,不访问,入栈,回退访问,向右,再一直向左
/** * Definition for binary tree * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */class Solution {public: vector<int> inorderTraversal(TreeNode *root) { stack<TreeNode *> pStack; while (root || !pStack.empty()) { while (root) { pStack.push(root); root = root->left; } if (!pStack.empty()) { root = pStack.top(); pStack.pop(); result.push_back(root->val); root = root->right; } } return result; }private: vector<int> result;};
3、后序
特征:叶节点直接访问;非叶节点,子树必须已访问,上一个被访问的必然是子节点
/** * Definition for binary tree * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */class Solution {public: vector<int> postorderTraversal(TreeNode *root) { if (root == NULL) { return result; } stack<TreeNode *> s; TreeNode *pre = NULL; s.push(root); while (!s.empty()) { root = s.top(); if (root->left == NULL && root->right == NULL) { result.push_back(root->val); pre = root; s.pop(); } else if (root->right != NULL && pre == root->right) { result.push_back(root->val); pre = root; s.pop(); } else if (root->left != NULL && pre == root->left) { result.push_back(root->val); pre = root; s.pop(); } else { if (root->right && pre != root->right) { s.push(root->right); } if (root->left && pre != root->left) { s.push(root->left); } } } return result; } private: vector<int> result;};
考虑到节点如果有左子树,则必然先背访问,那么需要考虑的是右子树如果存在,有没有被访问呢?
/** * Definition for binary tree * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */class Solution {public: vector<int> postorderTraversal(TreeNode *root) { if (root == NULL) { return result; } stack<TreeNode *> s; TreeNode *pre = NULL; TreeNode *cur = root; while (cur || !s.empty()) { while (cur) { s.push(cur); cur = cur->left; } // 一直向左子树方向探索 cur = s.top(); if (cur->right == NULL || pre == cur->right) { result.push_back(cur->val); pre = cur; s.pop(); cur = NULL; } else { cur = cur->right; } } return result; } private: vector<int> result;};
优化
迭代条件是
1、节点不空,此时栈可能为空,进入迭代会将节点入栈;
2、或者栈不空
因此在任何遍历出栈的时候,都可以保证栈是不空的,在出栈前也就没有必要判断栈是否为空。
优化的先序
/** * Definition for binary tree * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */class Solution {public: vector<int> preorderTraversal(TreeNode *root) { stack<TreeNode *> s; TreeNode *cur = root; while (cur || !s.empty()) { while (cur) { re.push_back(cur->val); s.push(cur); cur = cur->left; } cur = s.top(); cur = cur->right; s.pop(); } return re; }private: vector<int> re;};
优化的中序
/** * Definition for binary tree * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */class Solution {public: vector<int> inorderTraversal(TreeNode *root) { stack<TreeNode *> s; while (root || !s.empty()) { while (root) { s.push(root); root = root->left; } root = s.top(); s.pop(); re.push_back(root->val); root = root->right; } return re; }private: vector<int> re;};
优化的后序
/** * Definition for binary tree * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */class Solution {public: vector<int> postorderTraversal(TreeNode *root) { stack<TreeNode *> s; TreeNode *pre = NULL, *cur = root; while (cur || !s.empty()) { while (cur) { s.push(cur); cur = cur->left; } cur = s.top(); if (cur->right && pre != cur->right) { cur = cur->right; } else { re.push_back(cur->val); pre = cur; s.pop(); cur = NULL; } } return re; } private: vector<int> re;};
0 0
- 二叉树非递归遍历--迭代
- 非递归遍历二叉树
- 二叉树遍历非递归
- 非递归遍历二叉树
- 二叉树非递归遍历
- 二叉树非递归遍历
- 非递归遍历二叉树
- 二叉树非递归遍历
- 非递归遍历二叉树
- 非递归遍历二叉树
- 非递归遍历二叉树
- 非递归遍历二叉树
- 非递归遍历二叉树
- 二叉树非递归遍历
- 二叉树遍历--非递归
- 二叉树非递归遍历
- 非递归遍历二叉树
- 二叉树非递归遍历
- svn如何屏蔽/忽略不需要版本控制的文件(以UserInterfaceState.xcuserstate为例)
- Java实现多继承效果
- ROW_NUMBER() over
- 网络爬虫讲解及java代码实现
- 框架中框架子页面进行页面引导 window.location.replace的使用
- 二叉树非递归遍历--迭代
- AndroidManifest.xml详解
- cocos2d-x 求相交矩阵
- WCF快速入门——全自动方式编写WCF入门程序
- 白皮书6.3.1 小球下落
- MFC 程序的执行流程
- box2d 基础问答, 有空翻一下
- HDUJ 2090 算菜家
- APUE 第五章答案