首页 > 编程语言 >数据结构之二叉树(java语言版)

数据结构之二叉树(java语言版)

时间:2024-04-11 11:57:36浏览次数:32  
标签:结点 遍历 java data 二叉树 root 节点 语言版

之前的都是线性结构,而树结构在计算机应用中的应用更加广泛。linux中的目录结构,某些数据库的底层存储等,都是采用树结构进行构架的。

树的概念

线性表是一对一的关系,而树是一对多的关系。

树的结点:包含一个数据元素及若干指向子树的分支;
孩子结点:结点的子树的根称为该结点的孩子;
双亲结点:B 结点是A 结点的孩子,则A结点是B 结点的双亲;
兄弟结点:同一双亲的孩子结点; 堂兄结点:同一层上结点;
祖先结点: 从根到该结点的所经分支上的所有结点
子孙结点:以某结点为根的子树中任一结点都称为该结点的子孙
结点层:根结点的层定义为1;根的孩子为第二层结点,依此类推;
树的深度:树中最大的结点层
结点的度:结点子树的个数
树的度: 树中最大的结点度。
叶子结点:也叫终端结点,是度为 0 的结点;
分枝结点:度不为0的结点;
有序树:子树有序的树,如:家族树;
无序树:不考虑子树的顺序;

二叉树

最常用的树结构是二叉树。在计算机科学中,二叉树是每个结点最多有两个子树的树结构。通常子树被称作“左子树”和“右子树”。

1. 二叉树的性质

二叉树有以下几个性质:TODO(上标和下标)
性质1:二叉树第i层上的结点数目最多为 2****{i-1} (i≥1)。
性质2:深度为k的二叉树至多有2{k}-1个结点(k≥1)。
性质3:包含n个结点的二叉树的高度至少为log2 (n+1)
性质4:在任意一棵二叉树中,若终端结点的个数为n0,度为2的结点数为n2,则n0=n2+1

2、二叉树的种类

完全二叉树

若设二叉树的高度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第h层有叶子结点,并且叶子结点都是从左到右依次排布,这就是完全二叉树。

满二叉树

除了叶子结点外每一个结点都有左右子叶且叶子结点都处在最底层的二叉树

平衡二叉树

它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。

3、二叉树的遍历方式

先序遍历

先访问根节点,先序遍历左子树,先序遍历右子树

中序遍历

中序遍历左子树,访问根节点,中序遍历右子树

后序遍历

后序遍历左子树,后序遍历右子树,访问根节点

层次遍历

即按照层次访问,通常用队列来做。访问根,访问子女,再访问子女的子女

4、二叉树的存储方式

1、顺序存储

用一组连续的存储单元存放二叉树的数据元素。结点在数组中的相对位置蕴含着结点之间的关系。

比较浪费空间,基本不用。

2、链式存储

链式存储结构的每个结点由数据域、左指针域和右指针域组成。左指针和右指针分别指向下一层的二叉树。

在这里插入图片描述

5、实现

节点类

class Node {// 节点
    String data;
    Node rchild;
    Node lchild;
    boolean isDel;// 标识是否被删除

    public Node(String data) {// 构造方法,传入节点数据
        this.data = data;
        this.isDel = false;
    }

    public Node() {//构造方法
    }
}

建立树

树默认使用先序遍历的顺序进行建立。

public class BinTree {

    public BinTree() {// 构造方法

    }

    public Node init(Node root) {// 先序遍历的格式初始化

        String data;
        System.out.println("输入节点数据:");
        Scanner scanner = new Scanner(System.in);
        data = scanner.next();   //输入节点存储的数据

        if (data.equals("0")) {//设0为null,即不存在
            System.out.println("该节点为null");
        } else {
            System.out.println("data: " + data);
            root = new Node(data);

            root.lchild = init(root.lchild);//递归左孩子

            root.rchild = init(root.rchild);//递归右孩子

        }
        return root;
    }
}

遍历

使用递归进行遍历。

public void preOrder(Node root) {// 先序遍历
        if (root == null) {//递归终止条件,某个节点为null时结束
            return;
        }
        System.out.print(" " + root.data);//遍历根节点
        preOrder(root.lchild);//遍历左节点,直到某个左节点为null
        preOrder(root.rchild);//遍历右节点,直到某个右节点为null
    }

    public void midOrder(Node root) {// 中序遍历
        if (root == null) {
            return;
        }
        midOrder(root.lchild);
        System.out.print(" " + root.data);
        midOrder(root.rchild);
    }

    public void lastOrder(Node root) {// 后序遍历
        if (root == null) {
            return;
        }
        lastOrder(root.lchild);
        lastOrder(root.rchild);
        System.out.print(" " + root.data);

    }

测试

这是一个测试类,输入节点数据建立一个树后,进行遍历。

public static void main(String[] args) {
        BinTree binTree=new BinTree();
        Node root=binTree.init(new Node());

        System.out.println("先序遍历树:");
        binTree.preOrder(root);

        System.out.println("\n中序遍历树:");
        binTree.midOrder(root);

        System.out.println("\n后序遍历树:");
        binTree.lastOrder(root);
        
    }

就拿这个树作为模型测试。

输入0代表节点不存在,所以按照先序建立树,输入数据应该是:

ABC000DE00F00

在这里插入图片描述

输入数据:

输入节点数据:
A
data: A
输入节点数据:
B
data: B
输入节点数据:
C
data: C
输入节点数据:
0
该节点为null
输入节点数据:
0
该节点为null
输入节点数据:
0
该节点为null
输入节点数据:
D
data: D
输入节点数据:
E
data: E
输入节点数据:
0
该节点为null
输入节点数据:
0
该节点为null
输入节点数据:
F
data: F
输入节点数据:
0
该节点为null
输入节点数据:
0
该节点为null

输出遍历结果:

先序遍历树:
 A B C D E F
中序遍历树:
 C B A E D F
后序遍历树:
 C B E F D A

插入删除

关于插入和删除,由于树不是线性的,插入的位置有很多选择。对于以上的测试二叉树来说增加一个节点就有很多位置可以,若是插入那么位置就更多了。

对于数据的增加和删除需要更多的约束,避免产生极端的树。

加入不同的约束会产生不同的树,如哈夫曼树,搜索树等。

不同的树有不同的优势,用于满足需求。

在这里插入图片描述

标签:结点,遍历,java,data,二叉树,root,节点,语言版
From: https://www.cnblogs.com/cgl-dong/p/18128725

相关文章

  • 使用java代码删除nexus maven仓库中的jar包和pom.xml等组件
    pom.xml<?xmlversion="1.0"encoding="UTF-8"?><projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://ma......
  • 数据结构之图(java语言版)
    图是比树更复杂的结构,树是一对多的关系,图是多对多的关系。一、基本概念1、定义:图(graph)是由一些点(vertex)和这些点之间的连线(edge)所组成的;其中,点通常被成为"顶点(vertex)",而点与点之间的连线则被成为"边或弧"(edege)。通常记为,G=(V,E)。2、根据边是否有方向,将图可以划分......
  • 数据结构之Hash(java语言版)
    Hash表Hash也叫散列、哈希,是一种根据key-value对进行存储的数据结构。每个value对应一个key,这样查找的时候就无需遍历。Hash表使用数组作为底层结构,数组中每个区域都存储着Hash,这就是Hash表。列表、数组、树这些数据结构在查询数据时的时间复杂度通常为O(n),而Hash的时间复杂......
  • 数据结构之二叉搜索树(java语言版)
    之前介绍了树,主要实现了二叉树的代码。在二叉树的基础上有许多衍生的树,如二叉搜索树、哈夫曼树等,今天学习一下二叉搜索树。二叉搜索树二叉搜索树是二叉树的一种,是应用非常广泛的一种二叉树,英文简称为BST又被称为:二叉查找树、二叉排序树特点任意一个节点的值都大于其左子树所......
  • 数据结构之链表(c语言版)
    链表是线性表,链表的特点就是可以动态增减元素。种类有单向链表、双向链表,循环链表。一、单链表单链表的储存思想使用指针表示节点之间的逻辑关系,它的储存单元可以连续也可以不连续,每个储存单元需要储存信息和储存与后继节点的地址信息,储存单元又称之为节点。单链表由头指针唯......
  • 数据结构之栈(c语言版)
    栈(stack):在逻辑上是一种线性存储结构,它有以下几个特点:1、栈中数据是按照"后进先出(LIFO,LastInFirstOut)"方式进出栈的。2、向栈中添加/删除数据时,只能从栈顶进行操作。栈通常包括的三种操作:push、peek、pop。push--向栈中添加元素。peek--返回栈顶元素。pop--返......
  • 数据结构之队列(c语言版)
    队列(Queue):在逻辑上是一种线性存储结构。它有以下几个特点:1、队列中数据是按照"先进先出(FIFO,First-In-First-Out)"方式进出队列的。2、队列只允许在"队首"进行删除操作,而在"队尾"进行插入操作。队列通常包括的两种操作:入队列和出队列。队列的种类也很多,单向队列,双向队列,循......
  • 数据结构之二叉树(c语言版)
    之前的都是线性结构,而树结构在计算机应用中的应用更加广泛。linux中的目录结构,某些数据库的底层存储等,都是采用树结构进行构架的。树的概念线性表是一对一的关系,而树是一对多的关系。树的结点:包含一个数据元素及若干指向子树的分支;孩子结点:结点的子树的根称为该结点的孩子;双......
  • 数据结构之图(c语言版)
    图是比树更复杂的结构,树是一对多的关系,图是多对多的关系。一、基本概念1、定义:图(graph)是由一些点(vertex)和这些点之间的连线(edge)所组成的;其中,点通常被成为"顶点(vertex)",而点与点之间的连线则被成为"边或弧"(edege)。通常记为,G=(V,E)。2、根据边是否有方向,将图可以划分......
  • 链表(java语言版)
    链表(Linkedlist)是一种常见的基础数据结构,是一种线性表,但是并不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的指针(Pointer)。使用链表结构可以充分利用计算机内存空间,实现灵活的内存动态管理。但是链表失去了数组随机读取的优点,同时链表由于增加了结点的指针域......