一直想把二叉树的各种遍历做一个总结,在掌握好二叉树的4中遍历的基础上,其他的题目自然迎刃而解(可能有点夸张)。前、中、后序有递归和非递归的写法,一定要掌握,至于层序遍历嘛,直接非递归怼就是。
1. 前序遍历 Leetcode 144. Binary Tree Preorder Traversal
/*
* 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> res;
if( root == NULL )
return res;
__preorderTraversal(root, res);
return res;
}
private:
void __preorderTraversal(TreeNode* node, vector<int>& res){
if( node == NULL )
return;
res.push_back(node->val);
__preorderTraversal(node->left, res);
__preorderTraversal(node->right, res);
return;
}
};
//非递归实现
class Solution {
public:
vector<int> preorderTraversal(TreeNode* root) {
vector<int> res;
if(root == NULL)
return res;
stack<TreeNode*> stack;
TreeNode* cur = root;
while(cur != NULL || !stack.empty()){
while(cur != NULL){
res.push_back(cur->val);
stack.push(cur);
cur = cur->left;
}
cur = stack.top();
stack.pop();
cur = cur->right;
}
return res;
}
};
2. 中序遍历 Leetcode 94. Binary Tree Inorder Traversal
/**
* 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> res;
if(root == NULL)
return res;
__inorderTraversal(root, res);
return res;
}
private:
void __inorderTraversal(TreeNode* node, vector<int>& res){
if(node == NULL)
return;
__inorderTraversal(node->left, res);
res.push_back(node->val);
__inorderTraversal(node->right, res);
return;
}
};
//非递归实现
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
vector<int> res;
if( root == NULL )
return res;
stack<TreeNode*> stack;
TreeNode* cur = root;
while( cur != NULL || !stack.empty() ){
while( cur != NULL ){
stack.push( cur );
cur = cur->left;
}
cur = stack.top();
stack.pop();
res.push_back( cur->val );
cur = cur->right;
}
return res;
}
};
3. 后序遍历 Leetcode 145. Binary Tree Postorder Traversal
/**
* 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> res;
if( root == NULL )
return res;
__postorderTraversal(root, res);
return res;
}
private:
void __postorderTraversal(TreeNode* node, vector<int>& res){
if( node == NULL )
return;
__postorderTraversal(node->left, res);
__postorderTraversal(node->right, res);
res.push_back( node->val );
return;
}
};
//非递归实现
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root) {
vector<int> res;
if( root == NULL )
return res;
stack<TreeNode*> stack;
TreeNode* pre = NULL;
TreeNode* cur = root;
while( cur != NULL || !stack.empty() ){
while( cur != NULL ){
stack.push( cur );
cur = cur->left;
}
cur = stack.top();
stack.pop();
if( cur->right == NULL || pre == cur->right ){
res.push_back( cur->val );
pre = cur;
cur = NULL;
}
else{
stack.push(cur);
cur = cur->right;
}
}
return res;
}
};
4. 层序遍历 102. Binary Tree Level Order Traversal
/**
* 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) {
vector<vector<int>> res;
if(root == NULL)
return res;
queue<TreeNode*> q;
q.push(root);
int level_num = 1;
while( !q.empty() ){
int new_level_num = 0;
vector<int> level;
for(int i = 0; i < level_num; i++){
TreeNode* node = q.front();
q.pop();
level.push_back(node->val);
if(node->left){
q.push(node->left);
new_level_num++;
}
if(node->right){
q.push(node->right);
new_level_num++;
}
}
res.push_back(level);
level_num = new_level_num;
}
return res;
}
};
层序遍历有两变体:右视树和之字树。右视树就是站在一棵树的右边,看见的孩子,想法:开始就想到的是通过层序遍历来做,但是怎么得到每一层的最右边的孩子呢?当时想的是借鉴102,每一层用一个vector来存,然后通过for循环每次取最后一个值就好,但是发现有点麻烦,,,就没动手。后面发现用stack来存,后面直接top()就简单多了。
右视树 Leetcode 199. Binary Tree Right Side View
直接在102的基础上将vector换成了stack
/**
* 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> rightSideView(TreeNode* root) {
vector<int> res;
if(root == NULL)
return res;
queue<TreeNode*> q;
q.push(root);
int level_num = 1;
while( !q.empty() ){
int new_level_num = 0;
stack<int> level;
for(int i = 0; i < level_num; i++){
TreeNode* node = q.front();
q.pop();
level.push(node->val);
if(node->left){
q.push(node->left);
new_level_num++;
}
if(node->right){
q.push(node->right);
new_level_num++;
}
}
res.push_back( level.top() );
level_num = new_level_num;
}
return res;
}
};
之字树 Leetcode 103. Binary Tree Zigzag Level Order Traversal
需要两个辅助栈
/**
* 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>> zigzagLevelOrder(TreeNode* root) {
vector<vector<int>> res;
if(root == NULL)
return res;
stack<TreeNode*> levels[2];
int cur = 0;
int next = 1;
levels[cur].push(root);
while( !levels[cur].empty() || !levels[next].empty() ){
vector<int> temp;
while( !levels[cur].empty() ){
TreeNode* node = levels[cur].top();
levels[cur].pop();
temp.push_back(node->val);
if(cur == 0){
if(node->left)
levels[next].push(node->left);
if(node->right)
levels[next].push(node->right);
}
else{
if(node->right)
levels[next].push(node->right);
if(node->left)
levels[next].push(node->left);
}
}
res.push_back(temp);
if( levels[cur].empty() ){
cur = 1 - cur;
next = 1- next;
}
}
return res;
}
};
ps:1.剑指offer上题目真的是太经典了,得把它读厚才行,很多东西不要想着一次就做得十全十美,这是不可能的,多读一遍自然会有多读一遍的感悟。
2.波波老师Leetcode题解,https://github.com/liuyubobobo/Play-Leetcode,真的写得灰常灰常棒,作为菜鸡也只能抄抄波波老师的。
最后送自己一句,加油鸭!!!