二叉树的遍历主要有三种:
(1)先(根)序遍历(根左右)
(2)中(根)序遍历(左根右)
(3)后(根)序遍历(左右根)
中序
二叉树的中序遍历就是首先遍历左子树,然后访问当前节点,最后遍历右子树。
左-中-右
结果:[5,10,6,15,2]
1、递归法
这是思路最简单的方法,容易想到并且容易实现。递归的终止条件是当前节点是否为空。首先递归调用遍历左子树,然后访问当前节点,最后递归调用右子树。代码如下:
/**
* 递归
*/
public List<Integer> inorderTraversal(TreeNode root)
{
List<Integer> list = new ArrayList<>();
if (root == null)
return list;
inorder(root,list);
return list;
}
public static void inorder(TreeNode root, List list)
{
if (root != null)
{
inorder(root.left,list);
list.add(root.data);
inorder(root.right,list);
}
}
2、迭代法
在迭代方法中,从根节点开始找二叉树的最左节点,将走过的节点保存在一个栈中,找到最左节点后访问,对于每个节点来说,它都是以自己为根的子树的根节点,访问完之后就可以转到右儿子上了。代码如下:
public static class TreeNode
{
int data;
TreeNode left;
TreeNode right;
TreeNode(int val)
{
data = val;
}
}
/**
*非递归
*/
public List<Integer> inorderTraversal(TreeNode root)
{
List<Integer> list = new ArrayList<>();
Stack<TreeNode> stack = new Stack<>();
while (root != null || !stack.isEmpty())
{
while (root != null)
{
stack.push(root);
root = root.left;
}
if (!stack.isEmpty())
{
list.add(stack.peek().data);
root = stack.peek().right;
stack.pop();
}
}
return list;
}
前序
根左右
1、递归法
调整下访问顺序即可。代码如下:
//recursion
class Solution1 {
public:
vector<int> preorderTraversal(TreeNode* root) {
vector<int> ret;
preHelper(ret,root);
return ret;
}
private:
void preHelper(vector<int>& ret,TreeNode* root)
{
if(root==NULL)return;
ret.push_back(root->val);
preHelper(ret,root->left);
preHelper(ret,root->right);
}
2、迭代法
迭代法使用一个栈来保存当前不需要访问的节点。从根节点开始,访问当前节点,按照先右儿子后左儿子的顺序将当前节点的两个儿子压栈。当栈为空时说明遍历完毕。代码如下:
//iterative
class Solution2 {
public:
vector<int> preorderTraversal(TreeNode* root) {
vector<int> ret;
stack<TreeNode*> st;
if(root==NULL)return ret;
st.push(root);
while(!st.empty())
{
TreeNode *curr=st.top();
st.pop();
if(curr->right)st.push(curr->right);
if(curr->left)st.push(curr->left);
ret.push_back(curr->val);
}
return ret;
}
后序遍历
1、递归法
直接上代码:
左右根
//recursion
class Solution1 {
public:
vector<int> postorderTraversal(TreeNode* root) {
vector<int> ret;
postHelper(ret,root);
return ret;
}
private:
void postHelper(vector<int>& ret,TreeNode* root)
{
if(root==NULL)return;
postHelper(ret,root->left);
postHelper(ret,root->right);
ret.push_back(root->val);
}
};
2、迭代法
//iteration
class Solution1 {
public:
vector<int> postorderTraversal(TreeNode* root) {
vector<int> ret;
if(root==NULL)return ret;
stack<pair<TreeNode*,int>> st;
st.push(make_pair(root,0));
while(!st.empty())
{
TreeNode *curr=st.top().first;
if(st.top().second==1)
{
ret.push_back(curr->val);
st.pop();
}
else
{
st.top().second=1;
if(curr->right)st.push(make_pair(curr->right,0));
if(curr->left)st.push(make_pair(curr->left,0));
}
}
return ret;
}
层序遍历
class Solution {
public:
vector<int> levelOrder(TreeNode* root) {
vector<int> ret;
if(root==NULL)return ret;
queue<TreeNode*> q;
q.push(root);
while(!q.empty())
{
TreeNode *curr=q.front();
q.pop();
ret.push_back(curr->val);
if(curr->left)q.push(curr->left);
if(curr->right)q.push(curr->right);
}
return ret;
}
};