Loading

二叉树的各种遍历

94. 二叉树的中序遍历

题目要求:
给定一个二叉树,返回它的中序遍历。

思路:
递归遍历。

class Solution:
    def inorder(self, root, lst):
        if not root:
            return
        else:
            self.inorder(root.left, lst)
            lst.append(root.val)
            self.inorder(root.right, lst)

    def inorderTraversal(self, root: TreeNode) -> List[int]:
        ans = []
        self.inorder(root, ans)
        return ans
class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> ans = new LinkedList<>();
        inorder(root, ans);
        return ans;
    }

    public void inorder(TreeNode root, List<Integer> list){
        if(root == null){
            return;
        }
        inorder(root.left, list);
        list.add(root.val);
        inorder(root.right, list);
    }
}

中序遍历即先遍历左子树,再遍历根结点,最后遍历右子树,这是一个递归的概念,可以用一个栈来模拟中序遍历递归的过程。既然是先遍历左子树,就让指针一直向左走,遇到的结点先放入栈中,直到无路可走,就弹出一个结点,访问该结点(对这个结点进行某种操作)。接着访问这个结点的右子树,同样对其进行中序遍历。

class Solution:
    def inorderTraversal(self, root: TreeNode) -> List[int]:
        ans = []
        stack = []
        while stack or root:
            if root:
                stack.append(root)
                root = root.left
            else:
                node = stack.pop()
                ans.append(node.val)
                root = node.right

        return ans
class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> ans = new LinkedList<Integer>();
        Stack<TreeNode> stack = new Stack<>();
        while(!stack.empty() || root != null){
            if(root != null){
                stack.push(root);
                root = root.left;
            }else {
                TreeNode node = stack.pop();
                ans.add(node.val);
                root = node.right;
            }
        }
        return ans;
    }
}

144. 二叉树的前序遍历

题目要求:
给定一个二叉树,返回它的前序遍历。

思路:
同样从递归与辅助栈两个角度来对其进行遍历。

class Solution:
    def preorder(self, root, lst):
        if not root:
            return
        else:
            lst.append(root.val)
            self.preorder(root.left, lst)
            self.preorder(root.right, lst)
            
    def preorderTraversal(self, root: TreeNode) -> List[int]:
        ans = []
        self.preorder(root, ans)
        return ans
class Solution {
    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> ans = new LinkedList<>();
        preorder(root, ans);
        return ans;
    }
    
    public void preorder(TreeNode root, List<Integer> list){
        if (root == null){
            return;
        }
        list.add(root.val);
        preorder(root.left, list);
        preorder(root.right, list);
    }
}

这里先将右孩子放入栈中,再将左孩子放入栈中,这是由于栈先进后出的特性。而先序遍历先访问左子树,再访问右子树,因此要先将右孩子入栈。

class Solution:
    def preorderTraversal(self, root: TreeNode) -> List[int]:
        if not root:
            return []
        stack = [root]
        ans = []
        while stack:
            node = stack.pop()
            ans.append(node.val)            
            if node.right:
                stack.append(node.right)
            if node.left:
                stack.append(node.left)
        return ans
class Solution {
    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> ans = new LinkedList<>();
        Stack<TreeNode> stack = new Stack<>();
        if (root != null){
            stack.push(root);
        }
        while(!stack.empty()){
            TreeNode node = stack.pop();
            ans.add(node.val);
            if(node.right != null){
                stack.push(node.right);
            }
            if (node.left != null){
                stack.push(node.left);
            }
        }
        return ans;
    }
}

145. 二叉树的后序遍历

题目要求:
给定一个二叉树,返回它的后序遍历。

思路:
同样从递归与辅助栈两个角度来对其进行遍历。

class Solution:
    def postorder(self, root, lst):
        if not root:
            return
        else:
            self.postorder(root.left, lst)
            self.postorder(root.right, lst)
            lst.append(root.val)

    def postorderTraversal(self, root: TreeNode) -> List[int]:
        ans = []
        self.postorder(root, ans)
        return ans
class Solution {
    public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> ans = new LinkedList<>();
        postorder(root, ans);
        return ans;
    }

    public void postorder(TreeNode root, List<Integer> list){
        if (root == null){
            return;
        }
        postorder(root.left, list);
        postorder(root.right, list);
        list.add(root.val);
    }
}

后序遍历的非递归遍历比较特殊,如果按前面的思路,需要用到两个栈来模拟遍历的过程。不过还有一个更加巧妙的方法,代码如下:

class Solution:
    def postorderTraversal(self, root: TreeNode) -> List[int]:
        if not root:
            return []

        stack = [root]
        ans = []
        while stack:
            root = stack.pop()
            ans.append(root.val)
            if root.left:
                stack.append(root.left)
            if root.right:
                stack.append(root.right)
        return ans[::-1]
class Solution {
    public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> ans = new ArrayList<>();
        Stack<TreeNode> stack = new Stack<>();
        if (root != null){
            stack.push(root);
        }
        while(!stack.empty()){
            TreeNode node = stack.pop();
            ans.add(node.val);
            if(node.left != null){
                stack.push(node.left);
            }
            if (node.right != null){
                stack.push(node.right);
            }
        }
        Collections.reverse(ans);
        return ans;
    }
}

102. 二叉树的层序遍历

题目要求:
给你一个二叉树,请你返回其按层序遍历得到的节点值。(即逐层地,从左到右访问所有节点)。

思路:
层次遍历需要用到队列来辅助。

class Solution:
    def levelOrder(self, root: TreeNode) -> List[List[int]]:
        if not root:
            return []

        from collections import deque
        que = deque()
        que.append(root)
        ans = []
        while que:
            cur = []
            for _ in range(len(que)):
                node = que.popleft()
                cur.append(node.val)
                if node.left:
                    que.append(node.left)
                if node.right:
                    que.append(node.right)
            ans.append(cur)
        return ans
class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> ans = new ArrayList<>();
        if (root == null){
            return ans;
        }
        Queue<TreeNode> que = new LinkedList<>();
        que.offer(root);
        while (!que.isEmpty()){
            int size = que.size();
            List<Integer> cur = new LinkedList<>();
            for (int i = 0; i < size; i++) {
                TreeNode node = que.poll();
                cur.add(node.val);
                if (node.left != null){
                    que.offer(node.left);
                }
                if (node.right != null){
                    que.offer(node.right);
                }
            }
            ans.add(cur);
        }
        return ans;
    }
}

103. 二叉树的锯齿形层序遍历

题目要求:
给定一个二叉树,返回其节点值的锯齿形层序遍历。(即先从左往右,再从右往左进行下一层遍历,以此类推,层与层之间交替进行)。

思路:
只要对层次遍历的代码稍加改变,就可以实现锯齿形的层序遍历。加入一个标记,每隔一层就把那一层的遍历结果逆序一下。

class Solution {
    public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
        List<List<Integer>> ans = new ArrayList<>();
        if (root == null){
            return ans;
        }
        boolean isReverse = true;
        Queue<TreeNode> que = new LinkedList<>();
        que.offer(root);
        while (!que.isEmpty()){
            int size = que.size();
            List<Integer> cur = new ArrayList<>();
            isReverse = !isReverse;
            for (int i = 0; i < size; i++) {
                TreeNode node = que.poll();
                cur.add(node.val);
                if (node.left != null){
                    que.offer(node.left);
                }
                if (node.right != null){
                    que.offer(node.right);
                }
            }
            if (isReverse){
                Collections.reverse(cur);
            }
            ans.add(cur);
        }
        return ans;
    }
}
posted @ 2020-08-07 17:14  达芬骑驴  阅读(134)  评论(1编辑  收藏  举报