递归遍历
题目链接:144.前序遍历、94.中序遍历、145.后序遍历
思路:1.确定递归函数的参数和返回值、2.确定终止条件、3.确定单层递归的逻辑。
前序遍历是中左右、中序遍历是左中右、后序遍历是左右中。
前序遍历:
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<Integer>();
preorder(root, result);
return result;
}
public void preorder(TreeNode root,List<Integer> result){
if(root == null){
return;
}
result.add(root.val);
preorder(root.left,result);
preorder(root.right,result);
}
}
中序遍历:
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<Integer>();
inorder(root, result);
return result;
}
public void inorder(TreeNode root,List<Integer> result){
if(root == null){
return;
}
inorder(root.left,result);
result.add(root.val);
inorder(root.right,result);
}
}
后序遍历:
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<Integer>();
postorder(root, result);
return result;
}
public void postorder(TreeNode root,List<Integer> result){
if(root == null){
return;
}
postorder(root.left,result);
postorder(root.right,result);
result.add(root.val);
}
}
迭代遍历
前序遍历:
思路:前序遍历是中左右,每次先处理的是中间节点,先将根节点放入栈中,然后将右子节点加入栈,再加入左子节点。出栈时候是中左右的顺序。
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<>();
if (root == null){
return result;
}
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
while (!stack.isEmpty()){
TreeNode node = stack.peek();
stack.pop();
result.add(node.val);
if (node.right != null){
stack.push(node.right);
}
if (node.left != null){
stack.push(node.left);
}
}
return result;
}
}
后序遍历:
思路:后序遍历是左右中,入栈顺序是中左右,出栈顺序是中右左,最后反转得到左右中。
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<>();
if (root == null){
return result;
}
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
while (!stack.isEmpty()){
TreeNode node = stack.pop();
result.add(node.val);
if (node.left != null){
stack.push(node.left);
}
if (node.right != null){
stack.push(node.right);
}
}
Collections.reverse(result);
return result;
}
}
中序遍历:
思路:定义指针访问节点,将访问节点放入栈,从栈中弹出元素,弹出的元素就是待处理数据。
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<>();
if (root == null){
return result;
}
Stack<TreeNode> stack = new Stack<>();
TreeNode cur = root;
while (cur != null || !stack.isEmpty()){
if (cur != null){
stack.push(cur);
cur = cur.left;
}else{
cur = stack.pop();
result.add(cur.val);
cur = cur.right;
}
}
return result;
}
}