二叉树基础巩固之刷题篇

目录

树是什么呢?

二叉树

二叉树的特点:

特殊的二叉树

二叉树的性质

二叉树的存储结构分为:

遍历方式

例题

结语


首先让我们来了解一下树形结构树

树是什么呢?

树是一种非线性的数据结构,它是由n(n>=0)个有限结点组成一个具有层次关系的集合。把它叫做树是因
为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。

  • 根结点:根节点没有前驱结点。
  • 除根节点外,其余结点被分成是一棵结构与树类似的子树。每棵子树的根结点有且只有一个前驱,可以有0个或多个后继。
  • 因此,树是递归定义的。

二叉树

那么在知道了树是什么的情况下,我们可以进一步了解树形结构其中的一种特殊结构——二叉树

二叉树又是什么呢?

一棵二叉树是结点的一个有限集合,该集合或者为空,或者是由一个根节点加上两棵别称为左子树和右子树的二叉树组成。

二叉树的特点:

  1. 每个结点最多有两棵子树,即二叉树不存在度大于2的结点。
  2. 二叉树的子树有左右之分,其子树的次序不能颠倒。

特殊的二叉树

  1. 满二叉树:一个二叉树,如果每一个层的结点数都达到最大值,则这个二叉树就是满二叉树。也就是说,如果一个二叉树的层数为K,且结点总数是(2^k) -1 ,则它就是满二叉树。

  2. 完全二叉树:完全二叉树是效率很高的数据结构,完全二叉树是由满二叉树而引出来的。对于深度为K的,有n个结点的二叉树,当且仅当其每一个结点都与深度为K的满二叉树中编号从1至n的结点一一对应时称之为完全二叉树。 要注意的是满二叉树是一种特殊的完全二叉树。

二叉树的性质

  1. 若规定根节点的层数为1,则一棵非空二叉树的第i层上最多有2^(i-1) 个结点.

  2. 若规定根节点的层数为1,则深度为h的二叉树的最大结点数是2^h- 1.

  3. 对任何一棵二叉树, 如果度为0其叶结点个数为 n0, 度为2的分支结点个数为 n2,则有n0=n2+1

  4. 若规定根节点的层数为1,具有n个结点的满二叉树的深度,h=Log2(n+1). (ps:Log2(n+1)是log以2为
    底,n+1为对数)

  5. 对于具有n个结点的完全二叉树,如果按照从上至下从左至右的数组顺序对所有节点从0开始编号,则对
    于序号为i的结点有:

       1. 若i>0,i位置节点的双亲序号:(i-1)/2;i=0,i为根节点编号,无双亲节点
       2. 若2i+1<n,左孩子序号:2i+1,2i+1>=n否则无左孩子
       3. 若2i+2<n,右孩子序号:2i+2,2i+2>=n否则无右孩子
    

二叉树的存储结构分为:

顺序存储和类似与链表的链式存储

遍历方式

前序遍历:也叫先根遍历,根--左子树--右子树

中序遍历:左子树--根--右子树

后序遍历:左子树--右子树--根

层序遍历:每一层从左往右

例题

1.226. 翻转二叉树 - 力扣(LeetCode)

class Solution {
    public TreeNode invertTree(TreeNode root) {
        if(root==null)
            return null;
        TreeNode l=invertTree(root.left);
        TreeNode r=invertTree(root.right);
        root.left=r;
        root.right=l;
        return root;
    }
}

2.100. 相同的树 - 力扣(LeetCode)

class Solution {
    public boolean isSameTree(TreeNode p, TreeNode q) {
        if(p==null&&q==null){
            return true;
        }else if(p==null||q==null){
            return false;
        } else if (p.val!=q.val) {
            return false;
        }else{
            return isSameTree(p.left,q.left)&&isSameTree(p.right,q.right);
        }
    }
}

 3.101. 对称二叉树 - 力扣(LeetCode)

class Solution {
    public boolean isSymmetric(TreeNode root) {
        return check(root,root);
    }
    public boolean check(TreeNode a,TreeNode b){
        if(a==null&&b==null){
            return true;
        }else if(a==null||b==null){
            return false;
        }else{
            return a.val==b.val&&check(a.left,b.right)&&check(a.right,b.left);
        }
    }
}

 4.572. 另一棵树的子树 - 力扣(LeetCode)

class Solution {
    public boolean isSubtree(TreeNode root, TreeNode subRoot) {
        if (subRoot==null)
            return true;
        if(root==null)
            return false;
        return isSubtree(root.left,subRoot)||isSubtree(root.right,subRoot)||isSametree(root,subRoot);
    }
    public boolean isSametree(TreeNode a,TreeNode b){
        if(a==null&&b==null){
            return true;
        }else if(a==null||b==null){
            return false;
        } else if (a.val!=b.val) {
            return false;
        }else {
            return isSametree(a.left,b.left)&&isSametree(a.right,b.right);
        }
    }
}

 5.110. 平衡二叉树 - 力扣(LeetCode)

    class Solution {
        public boolean isBalanced(TreeNode root) {
            if(root==null){
                return true;
            }else {
                return Math.abs(height(root.left)-height(root.right))<=1&&isBalanced(root.left)&&isBalanced(root.right);
            }
        }
        public int height(TreeNode a){
            if(a==null)
                return 0;
            else {
                return Math.max(height(a.left),height(a.right))+1;
            }
        }
    }

6.二叉树遍历_牛客题霸_牛客网 (nowcoder.com)

import java.util.Scanner;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
class TreeNodek{
    public char val;
    public TreeNodek left;
    public TreeNodek right;
    public TreeNodek(char k){
        this.val=k;
    }
}
public class Main {
    public static int i=0;
    public static TreeNodek createTree(String str){
        TreeNodek node=null;
        if(str.charAt(i)!='#'){
            node=new TreeNodek(str.charAt(i));
            i++;
            node.left=createTree(str);
            node.right=createTree(str);
        }else {
            i++;
        }
        return node;
    }
    public static void zhongxu(TreeNodek k){
        if(k==null){
            return;
        }else {
            zhongxu(k.left);
            System.out.print(k.val+" ");
            zhongxu(k.right);
        }
    }
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNextLine()) { // 注意 while 处理多个 case
            String s=sc.nextLine();
            TreeNodek k=createTree(s);
            zhongxu(k);
        }
    }
}

 7.144. 二叉树的前序遍历 - 力扣(LeetCode)

class Solution {
    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> list=new ArrayList<>();
        Stack<TreeNode> stack= new Stack<TreeNode>();
        while(root!=null||!stack.isEmpty()){
            while(root!=null){
                list.add(root.val);
                stack.add(root);
                root=root.left;
            }
            root=stack.pop();
            root=root.right;
        }
        return list;
    }
}

 8.94. 二叉树的中序遍历 - 力扣(LeetCode)

class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> list=new ArrayList<>();
        Stack<TreeNode> stack= new Stack<TreeNode>();
        while(root!=null||!stack.isEmpty()){
            while(root!=null){
                stack.add(root);
                root=root.left;
            }
            root=stack.pop();
            list.add(root.val);
            root=root.right;
        }
        return list;
    }
}

 9.145. 二叉树的后序遍历 - 力扣(LeetCode)

class Solution {
    public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> list=new ArrayList<>();
        Stack<TreeNode> stack= new Stack<TreeNode>();
        TreeNode prev=null;
        while(root!=null||!stack.isEmpty()){
            while(root!=null){
                stack.add(root);
                root=root.left;
            }
            root=stack.pop();
            if(root.right==null||root.right==prev){
                list.add(root.val);
                prev=root;
                root=null;
            }else{
                stack.add(root);
                root=root.right;
            }
        }
        return list;
    }
}

10.106. 从中序与后序遍历序列构造二叉树 - 力扣(LeetCode)

class Solution {
    public static TreeNode create(int[] inorder,int[] postorder,int a1,int a2,int b1,int b2){
        if(a1>a2||b1>b2)
        return null;
        int t=a1;
        while(inorder[t]!=postorder[b2]&&t<=a2){
            t++;
        }
        int len=t-a1;
        TreeNode root=new TreeNode(postorder[b2]);
        root.left=create(inorder,postorder,a1,t-1,b1,b1+len-1);
        root.right=create(inorder,postorder,t+1,a2,b1+len,b2-1);
        return root;
    }
    public TreeNode buildTree(int[] inorder, int[] postorder) {
        if(inorder==null||postorder==null||inorder.length!=postorder.length)
            return null;
        int len=postorder.length-1;
        return create(inorder,postorder,0,len,0,len);
    }
}

11.105. 从前序与中序遍历序列构造二叉树 - 力扣(LeetCode)

class Solution {
    public static TreeNode create(int[] inorder,int[] preorder,int a1,int a2,int b1,int b2){
        if(a1>a2||b1>b2)
            return null;
        int t=a1;
        while(inorder[t]!=preorder[b1]&&t<=a2){
            t++;
        }
        int len=t-a1;
        TreeNode root=new TreeNode(preorder[b1]);
        root.left=create(inorder,preorder,a1,t-1,b1+1,b1+len);
        root.right=create(inorder,preorder,t+1,a2,b1+len+1,b2);
        return root;
    }
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        if(inorder==null||preorder==null||inorder.length!=preorder.length)
            return null;
        int len=preorder.length-1;
        return create(inorder,preorder,0,len,0,len);
    }
}

12.236. 二叉树的最近公共祖先 - 力扣(LeetCode)(LCA问题)

class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if(root==null)
            return null;
        if(root==p||root==q)
            return root;
        TreeNode l=lowestCommonAncestor(root.left,p,q);
        TreeNode r=lowestCommonAncestor(root.right,p,q);
        if(l!=null&&r!=null){
            return root;
        } else if (l!=null) {
            return l;
        }else {
            return r;
        }
    }
}

13.107. 二叉树的层序遍历 II - 力扣(LeetCode)

class Solution {
    public List<List<Integer>> levelOrderBottom(TreeNode root) {
        List<List<Integer>> z=new ArrayList<List<Integer>>();
        if(root==null)
            return z;
        Queue<TreeNode> queue=new LinkedList<TreeNode>();
        queue.add(root);
        while(!queue.isEmpty()){
            List<Integer> tmp=new ArrayList<Integer>();
            int size=queue.size();
            for (int i = 0; i < size; i++) {
                TreeNode k=queue.poll();
                tmp.add(k.val);
                TreeNode l=k.left;
                TreeNode r=k.right;
                if(l!=null){
                    queue.add(l);
                }
                if(r!=null){
                    queue.add(r);
                }
            }
            z.add(tmp);
        }
        Collections.reverse(z);
        return z;
    }
}

14.102. 二叉树的层序遍历 - 力扣(LeetCode)

class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> z=new ArrayList<List<Integer>>();
        if(root==null)
            return z;
        Queue<TreeNode> queue=new LinkedList<TreeNode>();
        queue.add(root);
        while(!queue.isEmpty()){
            List<Integer> tmp=new ArrayList<Integer>();
            int size=queue.size();
            for (int i = 0; i < size; i++) {
                TreeNode k=queue.poll();
                tmp.add(k.val);
                TreeNode l=k.left;
                TreeNode r=k.right;
                if(l!=null){
                    queue.add(l);
                }
                if(r!=null){
                    queue.add(r);
                }
            }
            z.add(tmp);
        }
        return z;
    }
}

15.606. 根据二叉树创建字符串 - 力扣(LeetCode)

class Solution {
    public String tree2str(TreeNode root) {
        if(root==null){
            return "";
        }
        if(root.left==null&&root.right==null){
            return Integer.toString(root.val);
        }
        if(root.right==null){
            return new StringBuffer().append(root.val).append("(").append(tree2str(root.left)).append(")").toString();
        }
        return new StringBuffer().append(root.val).append("(").append(tree2str(root.left)).append(")(").append(tree2str(root.right)).append(")").toString();
    }
}

结语

到此为止,您已经基本掌握二叉树所有的知识内容了,感谢您能非常耐心地一直看到这里,希望您能够在您的编程生涯中勇往直前!

  • 25
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值