树和二叉树

树的定义

树是由结点和边组成的,不存在环的一种数据结构
树的层次关系和节点的称呼:

  • A 结点是 B 结点和 C 结点的上级,则 A 就是 B 和 C 的父结点,B 和 C 是 A 的子结点。
  • B 和 C 同时是 A 的“孩子”,则可以称 B 和 C 互为兄弟结点。
  • A 没有父结点,则可以称 A 为根结点。
  • G、H、I、F 结点都没有子结点,则称 G、H、I、F 为叶子结

这是一颗深度为4的树
在这里插入图片描述

二叉树的定义

  1. 二叉树的特殊类型
  • 满二叉树,定义为除了叶子结点外,所有结点都有 2 个子结点。
  • 完全二叉树,定义为除了最后一层以外,其他层的结点个数都达到最大,并且最后一层的叶子结点都靠左排列。
    在这里插入图片描述
  1. 存储二叉树
    链式存储法:就是像链表一样,每个结点有三个字段,一个存储数据,另外两个分别存放指向左右子结点的指针

在这里插入图片描述

  • 顺序存储法,就是按照规律把结点存放在数组里,如下图所示,为了方便计算,我们会约定把根结点放在下标为 1 的位置。随后,B 结点存放在下标为 2 的位置,C 结点存放在下标为 3 的位置,依次类推。
    (根据这种存储方法,我们可以发现如果结点 X 的下标为 i,那么 X 的左子结点总是存放在 2 * i 的位置,X 的右子结点总是存放在 2 * i + 1 的位置。)
    在这里插入图片描述

  • 树的基本操作

  • 前序遍历,对树中的任意结点来说,先打印这个结点,然后前序遍历它的左子树,最后前序遍历它的右子树。

  • 中序遍历,对树中的任意结点来说,先中序遍历它的左子树,然后打印这个结点,最后中序遍历它的右子树。

  • 后序遍历,对树中的任意结点来说,先后序遍历它的左子树,然后后序遍历它的右子树,最后打印它本身。

在这里插入图片描述

二叉树代码实现过程:
在这里插入图片描述

package com.bai.webflux.webfluxdemo.test;


public class Node {
    private int value;        //节点的值
    private Node left;        //此节点的左子节点,数据类型为Node
    private Node right;       //此节点的右子节点,数据类型为Node

    public int getValue() {
        return value;
    }
    
    public Node getLeft() {
        return left;
    }
    public Node getRight() {
        return right;
    }

    public Node(int value, Node left, Node right) {
        this.value = value;
        this.left = left;
        this.right = right;
    }
    public String toString() {         //自定义的toString方法,为了方便之后的输出
        return this.value+" ";
    }
}




package com.bai.webflux.webfluxdemo.test;


public class StringTest {

    public static void main(String[] args) {
        Node D = new Node(4, null, null);
        Node E = new Node(5, null, null);
        Node H = new Node(6, null, null);
        Node B = new Node(2, D, E);
        Node C = new Node(3, null, H);
        Node A = new Node(1, B, C);//A为根节点
        System.out.print("先序遍历:");
        preOrderTraverse(A);
        System.out.print("\n中序遍历:");
        inOrderTraverse(A);
        System.out.print("\n后续遍历:");
        postOrderTraverse(A);
    }

    // 先序遍历
    public static void preOrderTraverse(Node node) {
        if (node == null)
            return;
        System.out.print(node.getValue() + " ");
        preOrderTraverse(node.getLeft());
        preOrderTraverse(node.getRight());
    }
    // 中序遍历
    public static void inOrderTraverse(Node node) {
        if (node == null)
            return;
        inOrderTraverse(node.getLeft());
        System.out.print(node.getValue() + " ");
        inOrderTraverse(node.getRight());
    }
    // 后序遍历
    public static void postOrderTraverse(Node node) {
        if (node == null)
            return;
        postOrderTraverse(node.getLeft());
        postOrderTraverse(node.getRight());
        System.out.print(node.getValue() + " ");
    }
}



输出:
先序遍历:1 2 4 5 3 6 
中序遍历:4 2 5 1 3 6 
后续遍历:4 5 2 6 3 1 

例子:按照层次顺序遍历并打印这棵树

package com.bai.webflux.webfluxdemo.test;


import java.util.LinkedList;

public class StringTest {

    public static void main(String[] args) {
        Node D = new Node(4, null, null);
        Node E = new Node(5, null, null);
        Node H = new Node(6, null, null);
        Node B = new Node(2, D, E);
        Node C = new Node(3, null, H);
        Node A = new Node(1, B, C);//A为根节点
        levelTraverse(A);
    }


    public static void levelTraverse(Node root) {
        if (root == null) {
            return;
        }
        //队列具有先进先出的特性
        LinkedList<Node> queue = new LinkedList<Node>();
        Node current = null;
        queue.offer(root); // 根节点入队

        while (!queue.isEmpty()) { // 只要队列中有元素,就可以一直执行,非常巧妙地利用了队列的特性
            current = queue.poll(); // 出队队头元素
            System.out.print("-->" + current.getValue());
            // 左子树不为空,入队
            if (current.getLeft() != null)
                queue.offer(current.getLeft());
            // 右子树不为空,入队
            if (current.getRight() != null)
                queue.offer(current.getRight());
        }
    }
}

输出:-->1-->2-->3-->4-->5-->6
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值