目录
✿二叉树的递归遍历❀
☞LeetCode144.前序遍历
☞LeetCode145.二叉树的后序遍历
☞LeetCode94.二叉树的中序遍历
✿二叉树的迭代遍历❀
☞LeetCode144.前序遍历
☞LeetCode145.二叉树的后序遍历
☞LeetCode94.二叉树的中序遍历
✿二叉树的统一迭代遍历❀
☞LeetCode144.前序遍历
☞LeetCode145.二叉树的后序遍历
☞LeetCode94.二叉树的中序遍历
✿二叉树的递归遍历❀
☞LeetCode144.前序遍历
链接:144.二叉树的前序遍历
给你二叉树的根节点
root
,返回它节点值的 前序 遍历。
前序遍历:根左右
递归三部曲:
每次写递归,都按照这三要素来写,可以保证大家写出正确的递归算法!
确定递归函数的参数和返回值: 确定哪些参数是递归的过程中需要处理的,那么就在递归函数里加上这个参数, 并且还要明确每次递归的返回值是什么进而确定递归函数的返回类型。
确定终止条件: 写完了递归算法, 运行的时候,经常会遇到栈溢出的错误,就是没写终止条件或者终止条件写的不对,操作系统也是用一个栈的结构来保存每一层递归的信息,如果递归没有终止,操作系统的内存栈必然就会溢出。
确定单层递归的逻辑: 确定每一层递归需要处理的信息。在这里也就会重复调用自己来实现递归的过程。
public List<Integer> preorderTraversal(TreeNode root) {
// 树中节点数目在范围 [0, 100] 内
// 根左右
List<Integer> result=new ArrayList<>();
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); //右
}
☞LeetCode145.二叉树的后序遍历
链接:145.二叉树的后序遍历
给你一棵二叉树的根节点
root
,返回其节点值的 后序遍历 。
后序遍历:左右根
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> result=new ArrayList<>();
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);
}
☞LeetCode94.二叉树的中序遍历
链接:94.二叉树的中序遍历
给定一个二叉树的根节点
root
,返回 它的 中序 遍历 。
中序遍历:左根右
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> result=new ArrayList<>();
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);
}
二叉树的递归遍历方式还是挺简单的,要知道前中后序的遍历顺序就能写出来
✿二叉树的迭代遍历❀
☞LeetCode144.前序遍历
链接:144.二叉树的前序遍历
能用递归实现的,栈也可以,二叉树迭代法的实现就是用栈,本来的前序遍历的顺序是根左右、因为栈是先进后出的,所以入栈顺序是根右左,代码如下:
public List<Integer> preorderTraversal(TreeNode root) {
// 迭代法
List<Integer> result=new ArrayList<>();
if(root==null){
return result;
}
Stack<TreeNode> st=new Stack<>();
st.push(root);
// 根右左
while(!st.isEmpty()){
TreeNode node=st.pop();
result.add(node.val);
if(node.right!=null){
st.push(node.right);
}
if(node.left!=null){
st.push(node.left);
}
}
return result;
}
☞LeetCode145.二叉树的后序遍历
链接:145.二叉树的后序遍历
后序遍历的迭代法和前序遍历差不多,后序遍历的顺序是左右根,反转一下就变成了根右左,这样就和前序遍历很相似了,入栈顺序是根左右,最后的结果再进行一个反转,代码如下:
public List<Integer> postorderTraversal(TreeNode root) {
// 迭代法
List<Integer> result=new ArrayList<>();
if(root==null){
return result;
}
Stack<TreeNode> st=new Stack<>();
st.push(root);
while(!st.isEmpty()){
TreeNode node=st.pop();
result.add(node.val);
if(node.left!=null){
st.push(node.left);
}
if(node.right!=null){
st.push(node.right);
}
}
// 反转
List<Integer> list=new ArrayList<>();
for (int i = result.size()-1; i >=0; i--) {
list.add(result.get(i));
}
return list;
}
☞LeetCode94.二叉树的中序遍历
链接:94.二叉树的中序遍历
到中序遍历这里就不一样了,因为前序遍历和后序遍历都可以转化为第一个遍历的节点是根节点,而中序遍历是要从最左边的节点开始,我下面的做法是将节点遍历至最左边,然后出栈,转向右节点,代码如下:
public List<Integer> inorderTraversal(TreeNode root) {
// 迭代法
List<Integer> result=new ArrayList<>();
if(root==null){
return result;
}
Stack<TreeNode> st=new Stack<>();
TreeNode cur=root;
while(cur!=null || !st.isEmpty()){
if(cur!=null){
st.push(cur);
cur=cur.left;
}else{
cur=st.pop();
result.add(cur.val);
cur=cur.right;
}
}
return result;
}
✿二叉树的统一迭代遍历❀
☞LeetCode144.前序遍历
链接:144.二叉树的前序遍历
二叉树的统一迭代遍历,前中后序的代码只是顺序不同,会了一个其他的自然就会了,代码如下:
public List<Integer> preorderTraversal(TreeNode root) {
// 统一迭代法
List<Integer> result=new ArrayList<>();
if(root==null){
return result;
}
Stack<TreeNode> st=new Stack<>();
st.push(root);
while(!st.isEmpty()){
TreeNode node=st.peek();
if(node==null){
st.pop(); //弹出空节点
result.add(st.pop().val);
}else{
st.pop();
if(node.right!=null){
st.push(node.right); //右
}
if(node.left!=null){
st.push(node.left); //左
}
st.push(node); // 中
st.push(null); // 空
}
}
return result;
}
☞LeetCode145.二叉树的后序遍历
链接:145.二叉树的后序遍历
public List<Integer> postorderTraversal(TreeNode root) {
//统一迭代法
List<Integer> result=new ArrayList<>();
if(root==null){
return result;
}
Stack<TreeNode> st=new Stack<>();
st.push(root);
while(!st.isEmpty()){
TreeNode node=st.peek();
if(node==null){
st.pop(); //弹出空节点
result.add(st.pop().val);
}else{
st.pop();
st.push(node); //中
st.push(null); // 空
if(node.right!=null){
st.push(node.right); // 右
}
if(node.left!=null){
st.push(node.left); // 左
}
}
}
return result;
}
☞LeetCode94.二叉树的中序遍历
链接:94.二叉树的中序遍历
public List<Integer> inorderTraversal(TreeNode root) {
// 统一迭代遍历
List<Integer> result=new ArrayList<>();
if(root==null){
return result;
}
Stack<TreeNode> st=new Stack<>();
st.push(root);
while(!st.isEmpty()){
TreeNode node=st.peek();
if(node==null){
st.pop(); // 弹出空节点
result.add(st.pop().val); //放入结果集
}else{
st.pop(); // 先出栈
if(node.right!=null){
st.push(node.right); // 右
}
st.push(node); // 中
st.push(null); // 空
if(node.left!=null){ // 左
st.push(node.left);
}
}
}
return result;
}