数据结构第九课——二叉树(相关概念及代码)

一、树的表示
孩子兄弟表示法:
在这里插入图片描述

二、二叉树
1、定义: 一棵二叉树是结点的一个有限集合,该集合或者为空,或者是由一个根节点加上两棵别称为左子树和右子树的二叉树组成。
2、特点:(1)每个结点最多有两棵子树,即二叉树不存在度大于2的结点;
(2)二叉树的子树有左右之分,其子树的次序不能颠倒,因此二叉树是有序树。
3、满二叉树和完全二叉树
(1)满二叉树:一个二叉树,每一层的结点数都达到最大值,若满二叉树的层数为n,则结点总数是2ⁿ-1;
(2)完全二叉树:完全二叉树是效率很高的数据结构,对于深度为k的,有n个结点的二叉树,当且仅当其每一个结点都与深度为k的满二叉树中编号从1到n的结点一一对应时称之为完全二叉树,数的时候,中间只要空了一个子结点,那就不是完全二叉树。
例:
在这里插入图片描述
4、性质:(1)若规定根结点的层数为1,则一棵非空二叉树的第i层上最多有2^(i-1)(i>0)个结点;(指的是同一层上的结点的个数)
(2)若规定只有根结点的二叉树深度为1,则深度为k的二叉树的最大结点数是(2^k)-1(k≥0);(指的是一整棵二叉树上所有的结点)
(3)对任何一棵二叉树,如果其叶结点个数为n0,度为2的非叶结点个数为n2,则有n0=n2+1;
(4)具有n个结点的完全二叉树的深度k为log2(n+1)(上取整);
(5)对于具有n个结点的完全二叉树,如果按照从上至下,从左至右的顺序对所有结点从0开始编号,则对于序号为i的结点有:
★ 若i>0,双亲序号:(i-1)/2;i=0,i为根结点编号无双亲结点;
★ 若2i+1<n,左孩子序号:2i+1,否则无左孩子;
★ 若2i+2<n,右孩子序号:2i+2,否则无右孩子。
【例题】一棵完全二叉树中共有1000个结点,则该二叉树中有()个叶子结点,()个非叶子结点,()个结点只有左孩子,()个结点只有右孩子,共有()层。(答案博客最后见)

三、二叉树的存储
(顺序二叉树和链式二叉树,使用的概率差不多,但是使用的场景不同。)
先说说二叉树的链式存储:
1、二叉树的链式存储:
在这里插入图片描述
2、二叉树的遍历:二叉树的题都是由递归实现的
(1)深度优先遍历
前序遍历:根,左,右
中序遍历:左,根,右
后序遍历:左,右,根
(2)广度优先遍历
层序遍历(如下图:A,B,C,D,E,F,G,H)
在这里插入图片描述
【例题】写出如下二叉树的前,中,后序遍历
在这里插入图片描述

二叉树的代码练习:
有关二叉树的习题(代码强化)
在这里插入图片描述

//前中后序遍历
class Node{
    public char val;
    public Node left;//左孩子
    public Node right;//右孩子
    //为什么把val的类型定义为char类型,输出的就是字母呢???定义为int类型输出的就是ASCII码对应的值???
    //首先因为你蠢,其次,一棵二叉树结点的值本来是字母,你把val定义为整型的,它不输出数字,难道输出字母吗?
    //要输出字母肯定要定义为字符类型啊!!!<=我犯的错误=>
    public Node(char val){
        this.val=val;
    }
}
public class BinaryTree {
    public Node buildTree(){  //构造二叉树
        Node A=new Node('A');
        Node B=new Node('B');
        Node C=new Node('C');
        Node D=new Node('D');
        Node E=new Node('E');
        Node F=new Node('F');
        Node G=new Node('G');
        Node H=new Node('H');
        A.left=B;A.right=C;B.left=D;B.right=E;//这里是构造二叉树的关键
        C.left=F;C.right=G;E.right=H;
        return A;
    }

    public void preOrderTraversal(Node root){   //前序遍历
        if(root==null){
            return;
        }
        System.out.printf(root.val+" ");
        preOrderTraversal(root.left);
        preOrderTraversal(root.right);
    }

    public void inOrderTraversal(Node root){   //中序遍历
        if(root==null){
            return;
        }
        inOrderTraversal(root.left);
        System.out.printf(root.val+" ");
        inOrderTraversal(root.right);
    }

    public void postOrderTraversal(Node root){   //后序遍历
        if(root==null){
            return;
        }
        postOrderTraversal(root.left);
        postOrderTraversal(root.right);
        System.out.printf(root.val+" ");
    }
    public static void main(String[] args) {
        BinaryTree binaryTree=new BinaryTree();
        Node root=binaryTree.buildTree();
        binaryTree.preOrderTraversal(root);
        System.out.println();
        binaryTree.inOrderTraversal(root);
        System.out.println();
        binaryTree.postOrderTraversal(root);
        System.out.println();
    }
}
/*
力扣上的一道题(前序遍历)
class Solution{
    public List<Integer> preOrderTraversal(TreeNode root){//要求返回型是list
        List<Integer> list=new ArrayList<>();//构造一个list存放遍历的元素
        if(root==null){
            return list;
        }
        System.out.printf(root.val+" ");
        list.add(root.val);//将得到的根传进list

        preOrderTraversal(root.left);
        list.addAll(left);//将左子树的值放进list

        preOrderTraversal(root.right);
        list.addAll(right);//将右子树的值放进list

        return list;//最后返回list
    }
}
*/

执行结果:
在这里插入图片描述
答案:【500,500,1,0,10】

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值