二叉树(Java)

树的概念

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

  • 有一个特殊的节点,称为根节点,根节点没有前驱节点

  • 除根节点外,其余节点被分成M(M>0)个互不相交的集合T1、T2、.....Tm,其中每一个集合Ti(1 <= i<=m)又是一棵与树类似的子树。每棵子树的根节点有且只有一个前驱,可以有0个或多个后继

  • 树是递归定义的

子树

  • 子树是不相交的

  • 除了根节点没有前驱节点,其余的每个节点都有且只有一个父节点

  • 假设树结构中边的个数为x,树节点的个数为n,他们之间的关系是x=n-1

  • 节点的"度":该节点包含的子树个数

  • 树的"度":树中最大节点的度


    image.png
  • 叶子节点:就是度为0的节点(比如上图中的M,J,K节点)

  • 非叶子节点:就是度不为0的节点,该节点存在子树

  • 根节点:没有前驱节点的节点,一个数只有一个根节点(比如上图的D节点)

  • 节点的层次:从根节点开始计算,对于上图来说,D根节点为第一层,I,J,K节点为第二层,M节点就是第三层

  • 树的高度:当前树中节点层次最大的即为树的高度(上图树的高度就是3)

二叉树概念

树中节点最大的度,为2的数就叫做二叉树,也就是数的度为2的树

  • 在二叉树中,一个节点最多有两颗子树,二叉树节点的度<=2

  • 二叉树的有左右之分,且子树的次序不能颠倒,因此二叉树是有序树


    image.png

二叉树性质

  • 在深度为K的二叉树中,最多存在2^k -1个节点

  • 在第K层中,该层最多有2^(k-1)个节点

  • 假设树结构中边的个数为x,树节点的个数为n,他们之间的关系是x=n-1,通过这个可以推出,度为2的节点(N2)和度为0的节点(N0)之间的关系:
    N0=N2+1

满二叉树和完全二叉树

  • 满二叉树:一个二叉树,如果每一个层的结点数都达到最大值,则这个二叉树就是满二叉树。也就是说,如果一个二叉树的层数为K,且结点总数是2^k -1,则它就是满二叉树。
  • 完全二叉树:完全二叉树是效率很高的数据结构,完全二叉树是由满二叉树而引出来的。对于深度为K的有n个结点的二叉树,当且仅当其每一个结点都与深度为K的满二叉树中编号从1至n的结点一一对应时称之为完全二叉树。要注意的是满二叉树是一种特殊的完全二叉树。(从视觉上来看,完全二叉树就是满二叉树缺少了右下角)

二叉树的创建

通过输入字符串序列如
8 7 5 1 -1 -1 -1 4 -1 -1 6 3 -1 -1 2 -1 -1
来创建二叉树

1、先创建两个类分别表示结点和树

/**
 * 1、设计一个类表示二叉树结点
 */
class Node{
    private int value;
    private Node left;
    private Node right;

    public Node(){

    }

    public Node(int value, Node left, Node right) {
        this.value = value;
        this.left = left;
        this.right = right;
    }

    public int getValue() {
        return value;
    }

    public void setValue(int value) {
        this.value = value;
    }

    public Node getLeft() {
        return left;
    }

    public void setLeft(Node left) {
        this.left = left;
    }

    public Node getRight() {
        return right;
    }

    public void setRight(Node right) {
        this.right = right;
    }
}

/**
 * 2、设计一个类表示二叉树
 */
class Tree{

    //树的深度
    private int index;
    private int leafVal;
    private Node head;

    public Node getHead() {
        return head;
    }

    public int getLeafVal() {
        return leafVal;
    }

    public void setLeafVal(int leafVal) {
        this.leafVal = leafVal;
    }

    public void setHead(Node head) {
        this.head = head;
    }

    /**
     * 打印
     */
    private void Print(int content){
        System.out.print(" "+content+" ");
    }
}

2、创建二叉树

class Tree{
  /**
     * 二叉树的创建
     */
    public void Create(String nodeStr){
        if(nodeStr == null || nodeStr.length() == 0)
            return;
        String[] strings = nodeStr.split(" ");
        int[] nums = new int[strings.length];
        for (int i = 0;i<nums.length;i++){
            int num = Integer.parseInt(strings[i].trim());
            nums[i] = num;
        }
        index = 0;
        head = CreateBinaryTree(nums);
    }
}

3、二叉树的遍历
对于二叉树来说,一共有四种遍历方式

  • 深度优先遍历(dfs):前序遍历,中序遍历,后序遍历

  • 广度优先遍历(bfs): 层序遍历

前序遍历:先访问根节点,然后递归访问左子树,在递归访问右子树(根左右,就是第一次访问该节点就打印,并且第一个节点一定是根节点)

    /**
     * 先序遍历:从二叉树的根结点出发,当第一次到达结点时就输出结点数据。
     */
    public void DLR(Node node){
        Print(node.getValue());

        if(node.getLeft() != null){
            DLR(node.getLeft());
        }

        if(node.getRight() != null){
            DLR(node.getRight());
        }

    }

中序遍历:先递归访问根的左子树,然后是根节点,最后是右子树(左根右,就是第二次访问到该节点时就打印,左子树节点都在根节点左侧,右子树节点在根节点右侧)

/**
     * 中序遍历:从二叉树的根结点出发,当第二次到达结点时就输出结点数据。
     */
    public void LDR(Node node){
        //找到最左边的结点
        if(node.getLeft() != null){
            LDR(node.getLeft());
        }
        Print(node.getValue());
        if(node.getRight() != null){
            LDR(node.getRight());
        }
    }

后序遍历:先递归访问左子树,在递归访问右子树,最后是根节点(左右根,就是第三次访问到该节点时就打印)

/**
     * 后序遍历:从二叉树的根结点出发,当第三次到达结点时就输出结点数据。
     */
    public void LRD(Node node){
        if(node.getLeft() != null){
            LRD(node.getLeft());
        }
        if(node.getRight() != null){
            LRD(node.getRight());
        }
        Print(node.getValue());
    }

层序遍历:将二叉树层层访问

/**
     * 层序遍历:按照树的层次自上而下的遍历二叉树。
     */
    public void BFS(Node node){
        Queue<Node> nodes = new LinkedList<>();
        nodes.add(node);
        while (!nodes.isEmpty()){
            Node poll = nodes.poll();
            Print(poll.getValue());
            if(poll.getLeft() != null){
                nodes.offer(poll.getLeft());
            }
            if(poll.getRight() != null){
                nodes.offer(poll.getRight());
            }
        }
    }

前序遍历:
8 7 5 1 -1 -1 -1 4 -1 -1 6 3 -1 -1 2 -1 -1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
中序遍历:
0 -1 0 -1 0 2 0 -1 0 -1 0 3 0 6 0 -1 0 -1 0 4 0 -1 0 -1 0 -1 0 1 0 5 0 7 0 8 0
后序遍历:
0 0 -1 0 -1 0 2 0 -1 0 -1 0 3 0 6 0 -1 0 -1 0 4 0 -1 0 -1 0 -1 0 1 0 5 0 7 0 8
层序遍历:
8 7 0 5 0 1 0 -1 0 -1 0 -1 0 4 0 -1 0 -1 0 6 0 3 0 -1 0 -1 0 2 0 -1 0 -1 0 0 0

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,204评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,091评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,548评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,657评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,689评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,554评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,302评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,216评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,661评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,851评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,977评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,697评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,306评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,898评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,019评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,138评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,927评论 2 355

推荐阅读更多精彩内容