二叉树的遍历

 

    二叉树的遍历主要有三种:

(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;
    }
};

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值