重温数据结构:树 及 Java 实现

数据结构,指的是数据的存储形式,常见的有线性结构(数组、链表,队列、栈),还有非线性结构(树、图等)。

今天我们来学习下数据结构中的

什么是树

线性结构中,一个节点至多只有一个头节点,至多只有一个尾节点,彼此连接起来是一条完整的线。

比如链表和数组:

而树,非线性结构的典型例子,不再是一对一,而变成了一对多(而图则可以是 多对多),如下图所示:

可以看到:

  • 图中的结构就像一棵倒过来的树,最顶部的节点就是“根节点 (root 节点)
  • 每棵树至多只有一个根节点
  • 根节点生出多个孩子节点,每个孩子节点只有一个父节点,每个孩子节点又生出多个孩子
  • 父亲节点 (parent) 和孩子节点 (child) 是相对的
  • 没有孩子节点的节点成为叶子节点 (leaf)

树的相关术语

根节点、父亲节点、孩子节点、叶子节点如上所述。

节点的度

一个节点直接含有的子树个数,叫做节点的度。比如上图中的 3 的度是 2,10 的度是 1。

树的度

一棵树中 最大节点的度,即哪个节点的子节点最多,它的度就是 树的度。上图中树的度为 2 。

节点的层次

从根节点开始算起,根节点算第一层,往后底层。比如上图中,3 的层次是 2,4 的层次是 4。

树的高度

树的高度是从叶子节点开始,自底向上增加

树的深度

与高度相反,树的深度从根节点开始,自顶向下增加

整个树的高度、深度是一样的,但是中间节点的高度 和 深度是不同的,比如上图中的 6 ,高度是 2 ,深度是 3。

树的两种实现

从上述概念可以得知,树是一个递归的概念,从根节点开始,每个节点至多只有一个父节点,有多个子节点,每个子节点又是一棵树,以此递归。

树有两种实现方式:

  • 数组
  • 链表

数组表示:

我们可以利用每个节点至多只有一个父节点这个特点,使用 父节点表示法 来实现一个节点:

public class TreeNode {

    private Object mData;   //存储的数据
    private int mParent;   //父亲节点的下标

    public TreeNode(Object data, int parent) {
        mData = data;
        mParent = parent;
    }

    public Object getData() {
        return mData;
    }

    public void setData(Object data) {
        mData = data;
    }

    public int getParent() {
        return mParent;
    }

    public void setParent(int parent) {
        mParent = parent;
    }
}

上述代码中,使用 角标 来指明父亲节点的位置,使用这个节点组成的数组就可以表示一棵树。

public static void main(String[] args){
    TreeNode[] arrayTree = new TreeNode[10];
}

用数组实现的树表示下面的树,(其中一种 )结果就是这样的:

数组实现的树节点使用角标表示父亲的索引,下面用链表表示一个节点和一棵树:

链表表示的节点:

public class LinkedTreeNode {

    private Object mData;   //存储的数据
    private LinkedTreeNode mParent;   //父亲节点的下标
    private LinkedTreeNode mChild;  //孩子节点的引用

    public LinkedTreeNode(Object data, LinkedTreeNode parent) {
        mData = data;
        mParent = parent;
    }

    public Object getData() {
        return mData;
    }

    public void setData(Object data) {
        mData = data;
    }

    public Object getParent() {
        return mParent;
    }

    public void setParent(LinkedTreeNode parent) {
        mParent = parent;
    }

    public LinkedTreeNode getChild() {
        return mChild;
    }

    public void setChild(LinkedTreeNode child) {
        mChild = child;
    }

}

使用引用,而不是索引表示父亲与孩子节点。

使用一个 List, 元素是 LinkedTreeNode,就可以表示一棵链表树:

public static void main(String[] args){
    LinkedList<LinkedTreeNode> linkedTree = new LinkedList<>();
}

这样只需知道 根节点就可以遍历整个树。知道某个节点也可以获取它的父亲和孩子。

树的几种常见分类及使用场景

树,为了更好的查找性能而生。

常见的树有以下几种分类:

  • 二叉树
  • 平衡二叉树
  • B 树
  • B+ 树
  • 哈夫曼树
  • 红黑树

接下来陆续介绍完回来补使用场景。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏余生开发

echarts太阳分布图-饼图来回穿梭

var dom = document.getElementById("container");

1442
来自专栏10km的专栏

SSD(Single Shot MultiBox Detector):create_list.sh io.cpp:187 Could not open or find file

今天在为SSD训练自己的数据时执行caff/data/VOC0712/create_list.sh时报了好多这个错误: E0412 16:28:31.6534...

2798
来自专栏FD的专栏

Effective Testing with RSpec 3 (英文版)(序言)

Early praise for Effective Testing with RSpec 3

1844
来自专栏c#开发者

Clean up your BizTalk databases

Here are a few scripts / stored procedures that most of the Biztalk newbies woul...

3454
来自专栏成长道路

org.apache.spark.sql.AnalysisException: Table or view not found: `traintext`.`train`; line 1 pos 14;

恭喜老铁,跟我遇到了一样的问题,接下来是解决方法: 遇到的问题: org.apache.spark.sql.AnalysisException: Table o...

1K0
来自专栏python3

openvpn linux客户端使用

内网服务器是linux的,需要连接openvpn,访问线上的应用服务。需要安装客户端,方法和服务器类似。

1252
来自专栏跟着阿笨一起玩NET

c# 使用timer定时器操作,上次定时到了以后,下次还未执行完怎么处理

------解决方案-------------------------------------------------------- 开始的时候,禁用定时器,你...

3041
来自专栏前端儿

Web 前端颜色值--字体--使用,整理整理

颜色值 CSS 颜色使用组合了红绿蓝颜色值 (RGB) 的十六进制 (hex) 表示法进行定义。对光源进行设置的最低值可以是 0(十六进制 00)。最高值是 2...

2762
来自专栏码匠的流水账

spring security reactive获取security context

本文主要研究下reactive模式下的spring security context的获取。

2142
来自专栏小鹏的专栏

ubuntu下C++如何调用python程序,gdb调试C++代码

Linux下gdb调试C++代码:http://jingyan.baidu.com/article/acf728fd464984f8e410a369.html ...

2809

扫码关注云+社区