二叉树遍历总结
2016-04-08 14:07
585 查看
二叉树遍历总结
1,前序遍历递归与非递归解法
1.1 前序遍历递归写法
1.2 前序遍历非递归写法(利用栈实现)
方法二:
2,中序遍历递归与非递归解法
2.1 中序遍历递归写法
2.2 中序遍历非递归写法
3,后续遍历的递归与非递归解法
3.1 后序遍历的递归解法
3.2 后续遍历的非递归解法
思路:前序遍历是root-left-right,后续遍历是left-right-root,通过修改非递归前序遍历的代码,使得遍历结构为root-right-left,然后将结果reverse一下即可以得到后续遍历的非递归结果
解法二,利用per指针与cur指针遍历二叉树
方法三:
/**
* 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<int> postorderTraversal(TreeNode *root) {
vector<int> result;
stack<TreeNode*> stk;
if(root==NULL) return result;
TreeNode* cur=root,*prev=NULL;
while(cur||!stk.empty())
{
if(cur){ //走到最左边
stk.push(cur);
cur=cur->left;
}
else{
cur = stk.top();
if(cur->right&&cur->right!=prev){ //如果右子树存在,且没有被访问过
cur=cur->right;//转向右边
stk.push(cur);//压入栈
cur=cur->left;//再走到最左
}
else{ //否则弹出结点
stk.pop();
result.push_back(cur->val);
prev=cur; //记录最近访问过的结点
cur=NULL; //设置当前结点已经访问过
}
}
}
return result;
}
};
1,前序遍历递归与非递归解法
1.1 前序遍历递归写法
/** * 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: void pre(TreeNode* root,vector<int>& vec){ if(root)vec.push_back(root->val); if(root->left)pre(root->left,vec); if(root->right)pre(root->right,vec); } vector<int> preorderTraversal(TreeNode* root) { vector<int> result; if(root==NULL) return result; pre(root,result); return result; } };
1.2 前序遍历非递归写法(利用栈实现)
/** * 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<int> preorderTraversal(TreeNode* root) { vector<int> result; if(root==NULL) return result; stack<TreeNode*> stk; stk.push(root); while(!stk.empty()){ TreeNode* tmp = stk.top(); stk.pop(); result.push_back(tmp->val); if(tmp->right)stk.push(tmp->right); if(tmp->left)stk.push(tmp->left); } return result; } };
方法二:
/** * 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<int> preorderTraversal(TreeNode* root) { vector<int> result; if(root==NULL) return result; stack<TreeNode*> stk; stk.push(root); result.push_back(root->val); while(!stk.empty()){ TreeNode* tmp = stk.top(); if(tmp->left){ stk.push(tmp->left); result.push_back(tmp->left->val); tmp->left=NULL; } else if(tmp->right){ stk.push(tmp->right); result.push_back(tmp->right->val); tmp->right=NULL; } else{ stk.pop(); } } return result; } };
2,中序遍历递归与非递归解法
2.1 中序遍历递归写法
/** * 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: void inorder(TreeNode* root,vector<int>& vec){ if(root->left)inorder(root->left,vec); if(root)vec.push_back(root->val); if(root->right)inorder(root->right,vec); } vector<int> inorderTraversal(TreeNode* root) { vector<int> result; if(root==NULL) return result; inorder(root,result); return result; } };
2.2 中序遍历非递归写法
/** * 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<int> inorderTraversal(TreeNode* root) { vector<int> result; if(root==nullptr)return result; stack<TreeNode*> stk; stk.push(root); while(!stk.empty()){ TreeNode* p = stk.top(); if(p->left){ stk.push(p->left); p->left=nullptr; } else{ result.push_back(p->val); stk.pop(); if(p->right) stk.push(p->right); } } return result; } };
3,后续遍历的递归与非递归解法
3.1 后序遍历的递归解法
/** * 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: void post(TreeNode* root,vector<int>& vec) { if(root->left)post(root->left,vec); if(root->right)post(root->right,vec); vec.push_back(root->val); } vector<int> postorderTraversal(TreeNode* root) { vector<int> result; if(root==NULL) return result; post(root,result); return result; } };
3.2 后续遍历的非递归解法
思路:前序遍历是root-left-right,后续遍历是left-right-root,通过修改非递归前序遍历的代码,使得遍历结构为root-right-left,然后将结果reverse一下即可以得到后续遍历的非递归结果
/** * 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<int> postorderTraversal(TreeNode *root) { stack<TreeNode*> nodeStack; vector<int> result; //base case if(root==NULL) return result; nodeStack.push(root); while(!nodeStack.empty()) { TreeNode* node= nodeStack.top(); result.push_back(node->val); nodeStack.pop(); if(node->left) nodeStack.push(node->left); if(node->right) nodeStack.push(node->right); } reverse(result.begin(),result.end()); return result; } };
解法二,利用per指针与cur指针遍历二叉树
#include <stack> using namespace std; class Solution { public: vector<int> postorderTraversal(TreeNode *root) { vector <int> res; if (!root) return res; stack<TreeNode*> s; TreeNode* prev = nullptr; s.push(root); while (!s.empty()) { TreeNode* cur = s.top(); //taking into account that if previous element coming from a subtree then it is either direct left or right child if (cur->right && cur->right == prev || !cur->right && cur->left == prev || !cur->left && !cur->right) { s.pop(); res.push_back(cur->val); prev = cur; continue; } if (cur->right) s.push(cur->right); if (cur->left) s.push(cur->left); } return res; } };
方法三:
/**
* 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<int> postorderTraversal(TreeNode *root) {
vector<int> result;
stack<TreeNode*> stk;
if(root==NULL) return result;
TreeNode* cur=root,*prev=NULL;
while(cur||!stk.empty())
{
if(cur){ //走到最左边
stk.push(cur);
cur=cur->left;
}
else{
cur = stk.top();
if(cur->right&&cur->right!=prev){ //如果右子树存在,且没有被访问过
cur=cur->right;//转向右边
stk.push(cur);//压入栈
cur=cur->left;//再走到最左
}
else{ //否则弹出结点
stk.pop();
result.push_back(cur->val);
prev=cur; //记录最近访问过的结点
cur=NULL; //设置当前结点已经访问过
}
}
}
return result;
}
};
相关文章推荐
- C#数据结构之顺序表(SeqList)实例详解
- Lua教程(七):数据结构详解
- 解析从源码分析常见的基于Array的数据结构动态扩容机制的详解
- C#数据结构之队列(Quene)实例详解
- C#数据结构揭秘一
- C#数据结构之单链表(LinkList)实例详解
- 数据结构之Treap详解
- 用C语言举例讲解数据结构中的算法复杂度结与顺序表
- C#数据结构之堆栈(Stack)实例详解
- C#数据结构之双向链表(DbLinkList)实例详解
- JavaScript数据结构和算法之图和图算法
- Java数据结构及算法实例:冒泡排序 Bubble Sort
- Java数据结构及算法实例:插入排序 Insertion Sort
- Java数据结构及算法实例:考拉兹猜想 Collatz Conjecture
- java数据结构之java实现栈
- java数据结构之实现双向链表的示例
- Java数据结构及算法实例:选择排序 Selection Sort
- Java数据结构及算法实例:朴素字符匹配 Brute Force
- Java数据结构及算法实例:汉诺塔问题 Hanoi
- Java数据结构及算法实例:快速计算二进制数中1的个数(Fast Bit Counting)