最近刷题目遇到了二叉树相关的题目,所以在此做好二叉树遍历的递归实现和迭代实现的方式
1.二叉树的节点定义
下面写出二叉树节点在Java、C++、Python中的定义
//=========================C++版本========================
/**
* 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) {}
* };
*/
//==================Java版本====================
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
//=====================python版本=======================
//# Definition for a binary tree node.
//# class TreeNode(object):
//# def __init__(self, val=0, left=None, right=None):
//# self.val = val
//# self.left = left
//# self.right = right
2.前中后序递归实现
二叉树遍历的递归实现比较容易(需要了解递归的本质),前序、中序和后续遍历只需要改变一下代码的位置顺序即可。代码实现如下:
//前序遍历
class Solution {
public:
void travel(TreeNode* root, vector<int>& ans){
if(root == nullptr) return;
ans.push_back(root->val);
travel(root->left, ans);
travel(root->right, ans);
}
vector<int> preorderTraversal(TreeNode* root) {
vector<int> ans;
travel(root, ans);
return ans;
}
};
//中序遍历
class Solution {
public:
void travel(TreeNode* root, vector<int>& ans){
if(root == nullptr) return;
travel(root->left, ans);
ans.push_back(root->val);
travel(root->right, ans);
}
vector<int> inorderTraversal(TreeNode* root) {
vector<int> ans;
travel(root, ans);
return ans;
}
};
//后续遍历
class Solution {
public:
void travel(TreeNode* root, vector<int>& ans){
if(root == nullptr) return;
travel(root->left, ans);
travel(root->right, ans);
ans.push_back(root->val);
}
vector<int> preorderTraversal(TreeNode* root) {
vector<int> ans;
travel(root, ans);
return ans;
}
};
3.前中后序迭代实现
二叉树的迭代遍历需要借助栈来实现,而且前序和后续遍历的实现比较简单,中序遍历的实现过程相较而言复杂一些
//前序遍历
class Solution {
public:
vector<int> preorderTraversal(TreeNode* root) {
stack<TreeNode* > st;
vector<int> result;
if(root == NULL) return result;
st.push(root);
while(!st.empty()){
TreeNode* node = st.top();
//C++中pop无返回值
st.pop();
result.push_back(node->val);
//非空的情况下加入到栈中,先右后左,这样弹出帐的时候就会先出左后右(和前序遍历的顺序是一样的)
if(node->right) st.push(node->right);
if(node->left) st.push(node->left);
}
return result;
}
};
//=======================后序遍历=============
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root) {
stack<TreeNode*> st;
vector<int> result;
if (root == NULL) return result;
st.push(root);
while (!st.empty()) {
TreeNode* node = st.top();
st.pop();
result.push_back(node->val);
if (node->left) st.push(node->left); // 相对于前序遍历,这更改一下入栈顺序 (空节点不入栈)
if (node->right) st.push(node->right); // 空节点不入栈
}
reverse(result.begin(), result.end()); // 将结果反转之后就是左右根的顺序了
return result;
}
};
中序遍历的实现相较于前面的前序和后序遍历的实现的过程要复杂一些,因为在其根节点的遍历夹在左右节点之间,这个时候我们就需要一个额外的指针来帮助我们遍历二叉树的了。详见下面代码:
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
vector<int> result;
stack<TreeNode* > st;
TreeNode* cur = root;
while(cur != NULL || !st.empty()){
if(cur != NULL){//指针用来访问节点,访问到最底层
st.push(cur);//将访问的节点放进栈
cur = cur->left;//左
}else{
cur = st.top();//从栈里弹出来的数据,就是要处理的数据
st.pop();
result.push_back(cur->val);//根
cur =cur -> right;//右
}
}
return result;
}
};
4.层序遍历
4.1迭代实现
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
queue<TreeNode* > que;
if(root != NULL) que.push(root);
vector<vector<int>> result;
while(!que.empty()){
int size = que.size();
vector<int> vec;
//这里一定要使用固定大小的size,不要使用que.size(),因为que.size()是不断变化的
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;
}
};
4.2递归实现
class Solution {
public:
void order(TreeNode* cur, vector<vector<int>>& result, int depth){
if(cur == nullptr) return;
if(result.size() == depth) result.push_back(vector<int>());
result[depth].push_back(cur->val);
order(cur->left, result, depth + 1);
order(cur->right, result, depth + 1);
}
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> result;
int depth = 0;
order(root, result, depth);
return result;
}
};