二叉树练习题(数据结构系列10)

目录

前言:

习题:

1. 检查两颗树是否相同。

2. 另一颗树的子树。

3. 翻转二叉树。

4. 判断一颗二叉树是否是平衡二叉树。

5. 对称二叉树。

6. 二叉树的构建及遍历。

7. 二叉树的分层遍历 。

8. 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先 。

9. 根据一棵树的前序遍历与中序遍历构造二叉树。 

10. 根据一棵树的中序遍历与后序遍历构造二叉树。

11. 二叉树创建字符串。

12. 二叉树前序非递归遍历实现 。

13. 二叉树中序非递归遍历实现。

14. 二叉树后序非递归遍历实现。

结束语:


前言:

上一次的博客中小编主要与大家分享了树、二叉树、满二叉树与完全二叉树的一些基础知识点,以及我们简单的实现了一些二叉树当中的一些算法,那么接下来我们就利用我们上次所学习的知识来进一步的展开练习一下吧!

习题:

1. 检查两颗树是否相同。

题目描述:

给你两棵二叉树的根节点 p 和 q ,编写一个函数来检验这两棵树是否相同。如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。

如下所示的两颗数数就是相同的树。

而下面的两颗树就不是相同的树,虽然结构一样但是值不一样也不是相同的树。

思路:
1.先判断两个树的根节点是不为空的,如果两者的树的根节点都是空的,那么也就说明二者的结构和值都是一样的。

2.在判断二者的结构是不是一样的如果一个是空的一个是不为空的那么说明这两颗树不是相同的树,否则就是一样的。

3.如果结构相同的话就判断它两的值是不是一样的,如果是一样的话就继续递归调用该函数向两颗树的左右分别向下查看,否则就直接返回false。

两颗树代码如下所示:
 

public class BinaryTree {
    public static class TreeNode{
        public int val;//值
        public TreeNode left;//左孩子
        public TreeNode right;//右孩子

        public TreeNode(int val) {
            this.val = val;
        }
    }

    TreeNode root = null;//根节点

    public TreeNode createTreeP() {
        TreeNode node1 = new TreeNode(1);
        TreeNode node2 = new TreeNode(2);
        TreeNode node3 = new TreeNode(3);
        TreeNode node4 = new TreeNode(4);
        TreeNode node5 = new TreeNode(5);
        TreeNode node6 = new TreeNode(6);
        TreeNode node7 = new TreeNode(7);
        //进行关联
        root = node1;
        node1.left = node2;
        node1.right = node3;
        node2.left = node4;
        node2.right = node5;
        node3.left = node6;
        node3.right = node7;
        return node1;
    }


    public TreeNode createTreeQ() {
        TreeNode node1 = new TreeNode(1);
        TreeNode node2 = new TreeNode(2);
        TreeNode node3 = new TreeNode(3);
        TreeNode node4 = new TreeNode(4);
        TreeNode node5 = new TreeNode(5);
        TreeNode node6 = new TreeNode(6);
        TreeNode node7 = new TreeNode(7);
        //进行关联
        root = node1;
        node1.left = node2;
        node1.right = node3;
        node2.left = node4;
        node2.right = node5;
        node3.left = node6;
        node3.right = node7;
        return node1;
    }
}

核心代码实现如下所示:
 

public boolean isSameTree(TreeNode p, TreeNode q) {
        //两个都是空
        if (p == null && q == null) {
            return true;
        }
        //一个是空一个不为空
        if (p != null && q == null || p == null && q != null)  {
            return false;
        }
        if (p.val != q.val) {
            return false;
        }
        //来到这里说明两者的值是一样的,且两者的结构是一样的。
        return isSameTree(p.left,q.left) &&isSameTree(p.right,q.right);
    }

结果如下所示:



2. 另一颗树的子树。

问题描述:

给你两棵二叉树 root 和 subRoot 。检验 root 中是否包含和 subRoot 具有相同结构和节点值的子树。如果存在,返回 true ;否则,返回 false 。

二叉树 tree 的一棵子树包括 tree 的某个节点和这个节点的所有后代节点。tree 也可以看做它自身的一棵子树。

如下所示的两颗树,一颗树是另一颗树的子树。

创建的两颗树的代码:
 

public static class TreeNode{
        public int val;//值
        public TreeNode left;//左孩子
        public TreeNode right;//右孩子

        public TreeNode(int val) {
            this.val = val;
        }
    }

    TreeNode root = null;//根节点

    public TreeNode createTreeP() {
        TreeNode node1 = new TreeNode(1);
        TreeNode node2 = new TreeNode(2);
        TreeNode node3 = new TreeNode(3);
        TreeNode node4 = new TreeNode(4);
        TreeNode node5 = new TreeNode(5);
        TreeNode node6 = new TreeNode(6);
        TreeNode node7 = new TreeNode(7);
        //进行关联
        root = node1;
        node1.left = node2;
        node1.right = node3;
        node2.left = node4;
        node2.right = node5;
        node3.left = node6;
        node3.right = node7;
        return node1;
    }


    public TreeNode createTreeQ() {
        TreeNode node1 = new TreeNode(2);
        TreeNode node2 = new TreeNode(4);
        TreeNode node3 = new TreeNode(5);
        //进行关联
        root = node1;
        node1.left = node2;
        node1.right = node3;
        return node1;
    }

核心代码如下所示:

public boolean isSubtree(TreeNode root, TreeNode subRoot) {
        //1.判断根是不是相同
        if (root == null && subRoot == null) {
            return true;
        }
        //判断两颗是不是一样
        if (isSameTree(root,subRoot)) {
            return true;
        }
        //判断root的左子树是不是和subRoot一样
        if (isSameTree(root.left, subRoot)) {
            return true;
        }
        //判断root的右子树和subRoot是不是一样
        if (isSameTree(root.right,subRoot)) {
            return true;
        }
        return false;
    }
    public boolean isSameTree(TreeNode p, TreeNode q) {
        //两个都是空
        if (p == null && q == null) {
            return true;
        }
        //一个是空一个不为空
        if (p != null && q == null || p == null && q != null)  {
            return false;
        }
        if (p.val != q.val) {
            return false;
        }
        //来到这里说明两者的值是一样的,且两者的结构是一样的。
        return isSameTree(p.left,q.left) && isSameTree(p.right,q.right);
    }


结果如下所示:



3. 翻转二叉树。

问题描述:

给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。

如下所示:

树的代码如下所示:
 

public static class TreeNode {
        public int val;
        public TreeNode left;
        public TreeNode right;

        public TreeNode(int val) {
            this.val = val;
        }
    }

    TreeNode root = null;

    public TreeNode createTree() {
        TreeNode node1 = new TreeNode(1);
        TreeNode node2 = new TreeNode(2);
        TreeNode node3 = new TreeNode(3);
        TreeNode node4 = new TreeNode(4);
        TreeNode node5 = new TreeNode(5);

        //关联
        root = node1;
        node1.left = node2;
        node1.right = node3;
        node2.left = node4;
        node2.right = node5;
        return root;
    }

核心代码如下所示:

public TreeNode invertTree(TreeNode root) {
        TreeNode cur = root;
        if (root == null) {
            return null;
        }
        //交换
        TreeNode tmp = root.left;
        root.left = root.right;
        root.right = tmp;
        //继续交换左右子树的孩子结点
        invertTree(root.left);
        invertTree(root.right);
        return cur;
    }


结果如下所示:



4. 判断一颗二叉树是否是平衡二叉树。

问题描述:

给定一个二叉树,判断它是否是高度平衡的二叉树。

本题中,一棵高度平衡二叉树定义为:

一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。

如上图所示,对于结点1来说左树的高度是4,右树的高度是2,左右高度差是2,超过了1,所以不是一颗高度平衡的二叉树。

但是下面的这个就是一颗高度平衡的二叉树。

创建树的代码如下所示:
 

    public static class TreeNode{
        public int val;
        public TreeNode left;
        public TreeNode right;

        public TreeNode(int val) {
            this.val = val;
        }
    }

    TreeNode root = null;

    public TreeNode createTree() {
        TreeNode node1 = new TreeNode(1);
        TreeNode node2 = new TreeNode(2);
        TreeNode node3 = new TreeNode(3);
        TreeNode node4 = new TreeNode(4);
        TreeNode node5 = new TreeNode(5);
        TreeNode node6 = new TreeNode(6);
        TreeNode node7 = new TreeNode(7);
        TreeNode node8 = new TreeNode(8);

        //关联
        root = node1;
        node1.left = node2;
        node1.right = node3;
        node2.left = node4;
        node2.right = node5;
        node3.left = node6;
        node4.left = node7;
        node4.right = node8;
        return root;
    }

核心代码如下所示:

    //判断是不是高度平衡的二叉树
    public boolean isBalanced(TreeNode root){
        return treeHeight(root) >= 0;
    }

    //计算二叉树的高度
    public int treeHeight(TreeNode root) {
        if (root == null) {
            return 0;
        }
        int leftHeight = treeHeight(root.left);
        if (leftHeight < 0) {
            return -1;
        }
        int rightHeight = treeHeight(root.right);
        if (rightHeight < 0) {
            return -1;
        }
        if (Math.abs(leftHeight - rightHeight) <= 1) {
            return Math.max(leftHeight,rightHeight) + 1;
        } else {
            return -1;
        }
    }


结果如下所示:



5. 对称二叉树。

问题描述:

给你一个二叉树的根节点 root , 检查它是否轴对称。

如下所示就是一颗对称的二叉树。

上述树的代码如下所示:

    public static class TreeNode{
        public int val;
        public TreeNode left;
        public TreeNode right;

        public TreeNode(int val) {
            this.val = val;
        }
    }

    TreeNode root = null;

    public TreeNode createTree() {
        TreeNode node1 = new TreeNode(1);
        TreeNode node2 = new TreeNode(2);
        TreeNode node3 = new TreeNode(2);
        TreeNode node4 = new TreeNode(3);
        TreeNode node5 = new TreeNode(3);
        TreeNode node6 = new TreeNode(4);
        TreeNode node7 = new TreeNode(4);

        //关联
        root = node1;
        node1.left = node2;
        node1.right = node3;
        node2.left = node4;
        node2.right = node6;
        node3.left = node7;
        node3.right = node5;
        return root;
    }

构造的树的结果如下所示:

核心代码如下所示:

//判断该树是否是对称二叉树
    public boolean isSymmetric(TreeNode root){
        if (root == null) {
            return true;
        }
        //判断子树的两边是不是对称的
        return isSymmetricChild(root.left,root.right);
    }

    public boolean isSymmetricChild(TreeNode leftTree, TreeNode rightTree) {
        if (leftTree != null && rightTree == null || leftTree == null && rightTree != null) {
            return false;
        }
        if (leftTree == null && rightTree == null) {
            return true;
        }
        if (leftTree.val != rightTree.val) {
            return false;
        }
        return isSymmetricChild(leftTree.left,rightTree.right) && isSymmetricChild(leftTree.right,rightTree.left);
    }


结果如下所示:


6. 二叉树的构建及遍历。

问题描述:

编一个程序,读入用户输入的一串先序遍历字符串,根据此字符串建立一个二叉树(以指针方式存储)。 例如如下的先序遍历字符串: ABC##DE#G##F### 其中“#”表示的是空格,空格字符代表空树。建立起此二叉树以后,再对二叉树进行中序遍历,输出遍历结果。

上述的前序遍历构建出来的二叉树如下所示:

思路:
这道题我们主要考虑的就是如何用前序遍历的方式创建出一颗二叉树,首先我们拿到的是一串字符串,其次我们就开始遍历字符串的每一个值,当我们遇到‘#’的时候就说明这课树的左孩子是没有的,如果接着在次遇到‘#’就说明这个结点的右孩子也是没有的。如果我们遍历到的是一个字母,我们就直接新建一个结点,然后再去以递归的方式去创建左孩子结点和右孩子结点就可以了。

创建出来的二叉树:
 

public class BinaryTree {
    static class TreeNode{
        public char val;
        public TreeNode left;
        public TreeNode right;

        public TreeNode(char val) {
            this.val = val;
        }
    }

    TreeNode root = null;
}

核心代码如下所示:

public class Test1 {
    //以前序遍历的方式创建一颗二叉树
    public static int i;
    public static BinaryTree.TreeNode crateTree(String str) {
        BinaryTree.TreeNode root = null;
        if (str.charAt(i) != '#') {
            root = new BinaryTree.TreeNode(str.charAt(i));
            i++;
            root.left = crateTree(str);
            root.right = crateTree(str);
        }else {
            i++;
        }
        return root;
    }
    //先序遍历
    public static void inOrder(BinaryTree.TreeNode root) {
        if (root == null) {
            return;
        }
        inOrder(root.left);
        System.out.print(root.val +" ");
        inOrder(root.right);
    }
    public static void main(String[] args) {
        String str = "ABC##DE#G##F###";
        BinaryTree.TreeNode ret = crateTree(str);
        inOrder(ret);
    }
}


结果如下所示:



7. 二叉树的分层遍历 。

问题描述:

给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。

如下图所示二叉树的层序遍历就是:3-9-20-15-7

思路:
我们可以借助队列来完成它,先将树的根节点入队,如果队列中的元素不为空,那么我们就直接出队首元素,打印并且如果将他的左右孩子结点依次入队。如果没有孩子结点的话就继续出队,直到队列为空为止。

树的创建:
 

class TreeNode3 {
    int val;
    TreeNode3 left;
    TreeNode3 right;
    TreeNode3() {

    }
    TreeNode3(int val) {
        this.val = val;
    }
    TreeNode3(int val, TreeNode3 left, TreeNode3 right) {
        this.val = val;
        this.left = left;
        this.right = right;
    }

    public TreeNode3 root;
    public TreeNode3 createTree() {
        TreeNode3 node1 = new TreeNode3(3);
        TreeNode3 node2 = new TreeNode3(9);
        TreeNode3 node3 = new TreeNode3(20);
        TreeNode3 node4 = new TreeNode3(15);
        TreeNode3 node5 = new TreeNode3(7);

        node1.left =  node2;
        node1.right = node3;
        node3.left = node4;
        node3.right = node5;
        this.root = node1;
        return root;
    }
}

核心代码如下所示:

public static void levelOrder(TreeNode3 root) {
        if (root == null) {
            return;
        }
        Queue<TreeNode3> queue = new LinkedList<>();
        TreeNode3 cur = root;
        queue.offer(cur);
        while (!queue.isEmpty()) {
            TreeNode3 top = queue.poll();
            //出队首元素
            System.out.print(top.val + " ");
            if (top.left != null) {
                queue.offer(top.left);
            }
            if (top.right != null) {
                queue.offer(top.right);
            }
        }
    }


结果如下所示: 



8. 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先 。

问题描述:

给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。

百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

如下图所示其中结点5和结点1的最近公共祖先是结点3。

 思路:

p和q的位置一共存在三种情况如下图所示:
 

该树的代码如下所示:

class TreeNode{
        public int val;
        public TreeNode left;
        public TreeNode right;

        public TreeNode(int val) {
            this.val = val;
        }
    }

    public TreeNode root;

    public TreeNode createTree() {
        TreeNode node1 = new TreeNode(1);
        TreeNode node2 = new TreeNode(2);
        TreeNode node3 = new TreeNode(3);
        TreeNode node4 = new TreeNode(4);
        TreeNode node5 = new TreeNode(5);
        TreeNode node6 = new TreeNode(6);
        TreeNode node7 = new TreeNode(7);
        TreeNode node8 = new TreeNode(8);
        TreeNode node0 = new TreeNode(0);

        node3.left = node5;
        node3.right = node1;
        node5.left = node6;
        node5.right = node2;
        node2.left = node7;
        node2.right = node4;
        node1.left = node0;
        node1.right = node8;
        this.root = node3;

        return root;
    }

核心代码如下所示:

//最近公共祖先
    public int lowestCommonAncestor(TreeNode root, int p, int q) {
        if (root == null) {
            return 0;
        }
        //1.先判断根节点是不是其中的一个
        if (root.val == p || root.val == q) {
            return root.val;
        }
        //2.如果不是其中的一个那么就向左和右分别递归的找p和q
        int leftRet = lowestCommonAncestor(root.left,p,q);
        int rightRet = lowestCommonAncestor(root.right,p,q);
        //如果左右都找到了p和q,也就是我们上图分析的第一种情况p和q在root的两侧.
        if (leftRet != 0 && rightRet != 0) {
            return root.val;
        } else if (leftRet != 0) {
            //如果右边没有找到p或者是q,左边找到了,那么就返回左边。
            return leftRet;
        } else if (rightRet != 0) {
            //如果左边没有找到p或者是q,右边找到了,那么就返回右边。
            return rightRet;
        }
        return 0;
    }


结果如下所示:



9. 根据一棵树的前序遍历与中序遍历构造二叉树。 

问题描述:

给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。

思路详细看代码解释。

核心代码如下所示:

//根据前序遍历的顺序和中序遍历的顺序构建二叉树
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        int len = preorder.length;
        return buildTreeChild(preorder,inorder,0,len - 1);
    }

    /**
     *
     * @param preorder
     * @param inorder
     * @param begin:构建树结点的起始位置
     * @param end:构建树结点结束的位置
     * @return
     */
    public int i = 0;

    public TreeNode buildTreeChild(int[] preorder, int[] inorder, int begin, int end) {
        //如果起始位置大于终止位置说明没有结点了
        if (begin > end) {
            return null;
        }
        //创建一个新的结点,新的结点就是直接来自前序遍历按顺序下来的结点。
        TreeNode root = new TreeNode(preorder[i]);
        //找到根结点在中序遍历中的位置
        int index = FindIndex(inorder,begin,end,preorder[i]);
        i++;
        //递归创建左树和右树
        root.left = buildTreeChild(preorder, inorder, begin, index - 1);
        root.right = buildTreeChild(preorder, inorder, index + 1, end);
        return root;
    }
    private int FindIndex(int[] inorder, int begin, int end, int key) {
        for (int k = begin; k <= end; k++) {
            if (inorder[k] == key) {
                return k;
            }
        }
        return -1;
    }


10. 根据一棵树的中序遍历与后序遍历构造二叉树。

问题描述:

给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。

思想:

结合上述根据一棵树的前序遍历与中序遍历构造二叉树我们就可以大概知道如何构造了,与上一个问题不同的点就是我们需要先构造右孩子结点在构造左孩子结点。,具体的思想看代码注释。

核心代码如下所示:

public TreeNode buildTree(int[] inorder, int[] postorder) {
        i = postorder.length - 1;
        return buildTreeChild(inorder,postorder,0, i);
    }

    public int i = 0;

    public TreeNode buildTreeChild(int[] inorder, int[] postorder, int begin, int end) {
        if (begin > end) {
            return null;
        }
        //后续遍历中的最后一个值就是根结点
        TreeNode root = new TreeNode(postorder[i]);
        //寻找后续遍历中根结点在中序遍历中的下标值
        int rootIndex = findIndex(inorder, begin, end, postorder[i]);
        i--;
        //向下去一递归构造左右子树
        root.right = buildTreeChild(inorder, postorder, rootIndex + 1, end);
        root.left = buildTreeChild(inorder, postorder, begin,rootIndex - 1);

        return root;
    }

    //计算根结点在中序遍历中的下标值
    private int findIndex(int[] inorder, int begin, int end, int key) {
        for (int j = begin; j <= end; j++) {
            if (inorder[j] == key) {
                return j;
            }
        }
        return -1;
    }

 


11. 二叉树创建字符串。

问题描述:

给你二叉树的根节点 root ,请你采用前序遍历的方式,将二叉树转化为一个由括号和整数组成的字符串,返回构造出的字符串。

空节点使用一对空括号对 "()" 表示,转化后需要省略所有不影响字符串与原始二叉树之间的一对一映射关系的空括号对。

 

思路:

首先我们先明确一点就是我们是通过二叉树的前序遍历俩创建字符串的,那么我们就来看一下上述这课二叉树的前序遍历是:1-2-4-3,那么我们通过前序遍历后转化成字符串就是1(2(4))(3),我们发现当我们遍历一颗树的左子树的时候我们会先入一个“( ”,然后再进行数字的打印如果没有左子树的的话那就直接打印一个“()”,然后我们在继续进行右子树的遍历。具体的解释详细见代码。

树的创建代码:
 

class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode() {}
    TreeNode(int val) { this.val = val; }
    TreeNode(int val, TreeNode left, TreeNode right) {
        this.val = val;
        this.left = left;
        this.right = right;
    }

    public TreeNode root;
    public TreeNode createTree() {
        TreeNode node1 = new TreeNode(1);
        TreeNode node2 = new TreeNode(2);
        TreeNode node3 = new TreeNode(3);
        TreeNode node4 = new TreeNode(4);

        node1.left =  node2;
        node1.right = node3;
        node2.left = node4;
        this.root = node1;
        return root;
    }
}

核心代码如下所示:

public static String tree2str(TreeNode root) {
        if (root == null) {
            return null;
        }
        //创建一个StringBuilder来保存字符串
        StringBuilder stringBuilder = new StringBuilder();
        tree2strChild(root,stringBuilder);
        return stringBuilder.toString();
    }

    public static void tree2strChild(TreeNode root, StringBuilder stringBuilder) {
        if (root == null ) {
            return;
        }
        //如果根结点的值不为空,就将根结点的值先放进来
        stringBuilder.append(root.val);
        //判断是否有左子树
        if (root.left != null) {
            //存在左子树就先打印 ( ,然后再进行递归调用他的左子树,结束后打印 )
            stringBuilder.append("(");
            tree2strChild(root.left,stringBuilder);
            stringBuilder.append(")");
        }else {
            //左边为空
            if (root.right != null) {
                //右边不为空
                stringBuilder.append("()");
            }else {
                //左右都是空的
                return;
            }
        }
        //如果右子树不为空的话和左边不为空的情况一样,先打印 ( ,然后再递归调用它的右子树,最后打印 )。
        if (root.right == null) {
            return;
        }else {
            //右边不为空
            stringBuilder.append("(");
            tree2strChild(root.right,stringBuilder);
            stringBuilder.append(")");
        }
    }


结果如下所示:

 


 

12. 二叉树前序非递归遍历实现 。

问题描述:

给你二叉树的根节点 root ,返回它节点值的 前序 遍历。

思路:

我们之前是通过递归来实现一颗二叉树的前序遍历的那么现在我们要用非递归要怎么实现呢?
我们是通过借助栈来实现的,首先我们先定义一个结点变量cur来记录当前的根结点,如果说根结点不等于null或者是栈不为空的时候我们就进入循环中,如果cur不为空,那么我们就让当前的结点入栈并打印,然后我们在让cur = cur.left。也就是继续往左边走,如果左边的子树为空的话我就跳出里面的循环往右边走,我可以在定义一个变量top用来记录当前的栈弹出的元素,然后我们将这弹出元素的右子树的结点赋值给cur,然后再进行循环。

树的代码如下所示:
 

class TreeNode2 {
    int val;
    TreeNode2 left;
    TreeNode2 right;
    TreeNode2() {}
    TreeNode2(int val) { this.val = val; }
    TreeNode2(int val, TreeNode2 left, TreeNode2 right) {
        this.val = val;
        this.left = left;
        this.right = right;
    }

    public TreeNode root;
    public TreeNode createTree() {
        TreeNode node1 = new TreeNode(1);
        TreeNode node2 = new TreeNode(2);
        TreeNode node3 = new TreeNode(3);

        node1.right = node2;
        node2.left = node3;

        this.root = node1;
        return root;
    }
}

核心代码如下所示:

public static void preorderTraversal(TreeNode root) {
        if (root == null) {
            return;
        }
        TreeNode cur = root;
        Deque<TreeNode> stack = new LinkedList<>();
        while (cur != null || !stack.isEmpty())  {
            while (cur != null) {
                stack.push(cur);
                System.out.print(cur.val + " ");
                cur = cur.left;
            }
            TreeNode top = stack.pop();
            cur = top.right;
        }
    }


结果如下所示:

 



13. 二叉树中序非递归遍历实现。

问题描述:

给定一个二叉树的根节点 root ,返回 它的 中序 遍历 。

 思想:

同样以上面这课二叉树为例,我们的基本思想和前序遍历的一样也是借助栈来完成的,只是我们打印根结点的时间不一样了。

核心代码如下所示:

public static void inorderTraversal(TreeNode root) {
        if (root == null) {
            return;
        }
        TreeNode cur = root;
        Deque<TreeNode> stack = new LinkedList<>();
        while (cur != null || !stack.isEmpty()) {
            while (cur != null) {
                stack.push(cur);//将根结点入栈
                cur = cur.left;//在继续往左边走
            }
            TreeNode top = stack.pop();//弹出栈顶元素
            System.out.print(top.val + " ");
            cur = top.right;
        }
    }


结果如下所示:

 



14. 二叉树后序非递归遍历实现。

问题描述:

给你一棵二叉树的根节点 root ,返回其节点值的 后序遍历 

核心代码如下所示:

public static void postorderTraversal(TreeNode root) {
        if (root == null) {
            return;
        }
        TreeNode cur = root;
        TreeNode prev = null;//用来记录打印过的结点
        Deque<TreeNode> stack = new LinkedList<>();
        while (cur != null || !stack.isEmpty()) {
            while (cur != null) {
                stack.push(cur);
                cur = cur.left;
            }
            TreeNode top = stack.peek();
            if (top.right == null || top.right == prev) {
                System.out.print(top.val + " ");
                stack.pop();
                prev = top;
            }else {
                cur = top.right;
            }
        }
    }


结果如下所示:

 



结束语:

好啦,有关于二叉树的一些基础练习题小编就与大家分享到这里啦!想要继续深度学习的同学也可以自己去刷一些题,来加强对知识的理解,希望对大家有所帮助,想要学习的同学记得关注小编和小编一起学习吧!如果文章中有任何错误也欢迎各位大佬及时为小编指点迷津(在此小编先谢过各位大佬啦!)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

努力敲代码的小白✧٩(ˊωˋ*)و✧

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值