二叉树的各种遍历
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;
}
}