二叉树

本文介绍了树的基本概念,包括根节点、父节点、子节点、兄弟节点、叶节点、高度、深度和层。特别讨论了二叉树的定义,满二叉树和完全二叉树的区别,并展示了链式存储法和基于数组的顺序存储法来表示二叉树。同时,详细讲解了二叉树的前序、中序和后序遍历方法,并给出了相应的Java实现。最后,探讨了二叉树遍历的时间复杂度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

树的基本概念
在这里插入图片描述
如上图所示:

根节点:没有父节点的节点,如E

父节点:A是B的父节点

子节点:B是A的子节点

兄弟节点:拥有同一父节点的节点,如BCD是兄弟节点

叶节点:没有子节点的节点,如G、H、I、J、K、L

高度:节点到叶子节点的最长路径,如E节点的高度是3,A节点的高度是2,B节点是1,G节点是0

深度:根节点到此节点所经历的边的个数,如E的深度是0,A的深度是1

层:节点的深度+1

树的高度:根节点的高度

二叉树

每个节点最多有两个叉,分别是左子节点和右子节点。

满二叉树:除了叶子结点之外,每个节点都有两个节点的树。

完全二叉树:叶子节点都在最底下两层,最后一层的叶子节点都靠左排列,并且除了最后一层,其他层的节点个数都要达到最大。

满二叉树可以看做是一个特殊的完全二叉树。

二叉树如何表示?

1、链式存储法

在这里插入图片描述
每个节点都有三个字段,data存储数据,left表示节点的左子节点的指针,right表示节点的右子节点的指针。

2、基于数组的顺序存储法

在这里插入图片描述
把根节点存储在数组下标为i=1的位置,左子节点在数组中的下标就是2i=2的位置,右子节点在数组中的下标就是2i+1=3的位置。

这是在完全二叉树的情况下,可以很好的利用数组的空间,但若不是完全二叉树甚至于比较极端的情况,数据都分布在根节点的左子节点树或者右子节点树,那么数组就会出现大量未被使用的元素,造成空间浪费。

二叉树遍历
在这里插入图片描述

public class BinaryTreeNode {
    private int data;
    private BinaryTreeNode leftNode;
    private BinaryTreeNode rightNode;

    public BinaryTreeNode(int data, BinaryTreeNode leftNode, BinaryTreeNode rightNode){
        this.data = data;
        this.leftNode = leftNode;
        this.rightNode = rightNode;
    }

    public BinaryTreeNode(){}

    public int getData() {
        return data;
    }

    public void setData(int data) {
        this.data = data;
    }

    public BinaryTreeNode getLeftNode() {
        return leftNode;
    }

    public void setLeftNode(BinaryTreeNode leftNode) {
        this.leftNode = leftNode;
    }

    public BinaryTreeNode getRightNode() {
        return rightNode;
    }

    public void setRightNode(BinaryTreeNode rightNode) {
        this.rightNode = rightNode;
    }
}

前序遍历

打印顺序是:根节点->左子节点->右子节点

/**
     * 前序遍历
     *
     * @param root
     */
    public static void preOrder(BinaryTreeNode root) {
        if (root == null) return;
        System.out.print(root.getData() + " ");
        preOrder(root.getLeftNode());
        preOrder(root.getRightNode());
    }

    public static void main(String[] args) {
        BinaryTreeNode node10 = new BinaryTreeNode(10, null, null);
        BinaryTreeNode node8 = new BinaryTreeNode(8, null, null);
        BinaryTreeNode node9 = new BinaryTreeNode(9, null, node10);
        BinaryTreeNode node4 = new BinaryTreeNode(4, null, null);
        BinaryTreeNode node5 = new BinaryTreeNode(5, node8, node9);
        BinaryTreeNode node6 = new BinaryTreeNode(6, null, null);
        BinaryTreeNode node7 = new BinaryTreeNode(7, null, null);
        BinaryTreeNode node2 = new BinaryTreeNode(2, node4, node5);
        BinaryTreeNode node3 = new BinaryTreeNode(3, node6, node7);
        BinaryTreeNode node1 = new BinaryTreeNode(1, node2, node3);

        preOrder(node1);
    }

运行结果:

1 2 4 5 8 9 10 3 6 7 

中序遍历

打印顺序是:左子节点->根节点->右子节点

/**
     * 中序遍历
     * @param
     */
    public static void inOrder(BinaryTreeNode root){
        if (root == null) return;
        inOrder(root.getLeftNode());
        System.out.print(root.getData() + " ");
        inOrder(root.getRightNode());
    }

    public static void main(String[] args) {
        BinaryTreeNode node10 = new BinaryTreeNode(10, null, null);
        BinaryTreeNode node8 = new BinaryTreeNode(8, null, null);
        BinaryTreeNode node9 = new BinaryTreeNode(9, null, node10);
        BinaryTreeNode node4 = new BinaryTreeNode(4, null, null);
        BinaryTreeNode node5 = new BinaryTreeNode(5, node8, node9);
        BinaryTreeNode node6 = new BinaryTreeNode(6, null, null);
        BinaryTreeNode node7 = new BinaryTreeNode(7, null, null);
        BinaryTreeNode node2 = new BinaryTreeNode(2, node4, node5);
        BinaryTreeNode node3 = new BinaryTreeNode(3, node6, node7);
        BinaryTreeNode node1 = new BinaryTreeNode(1, node2, node3);

        inOrder(node1);
    }

运行结果:

4 2 8 5 9 10 1 6 3 7 

后序遍历

打印顺序是:左子节点->右子节点->根节点

/**
     * 后序遍历
     * @param
     */
    public static void postOrder(BinaryTreeNode root){
        if (root == null) return;
        postOrder(root.getLeftNode());
        postOrder(root.getRightNode());
        System.out.print(root.getData() + " ");
    }

    public static void main(String[] args) {
        BinaryTreeNode node10 = new BinaryTreeNode(10, null, null);
        BinaryTreeNode node8 = new BinaryTreeNode(8, null, null);
        BinaryTreeNode node9 = new BinaryTreeNode(9, null, node10);
        BinaryTreeNode node4 = new BinaryTreeNode(4, null, null);
        BinaryTreeNode node5 = new BinaryTreeNode(5, node8, node9);
        BinaryTreeNode node6 = new BinaryTreeNode(6, null, null);
        BinaryTreeNode node7 = new BinaryTreeNode(7, null, null);
        BinaryTreeNode node2 = new BinaryTreeNode(2, node4, node5);
        BinaryTreeNode node3 = new BinaryTreeNode(3, node6, node7);
        BinaryTreeNode node1 = new BinaryTreeNode(1, node2, node3);

        postOrder(node1);
    }

运行结果:

4 8 10 9 5 2 6 7 3 1 

时间复杂度

与节点个数n成正比,所以时间复杂度是O(n)。

原文:https://gper.club/articles/7e7e7f7ff7g54gcdg67

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值