数据结构之初识树

大家好,我是1z,从这篇文章开始我将带着大家走近’树’的世界。作为数据结构中不可缺少的一环,它又有哪些耐人寻味的故事呢?

当我第一次听数据结构这门课的时候,提到‘树’这个概念的时候。难免会看向窗外,满眼的郁郁葱葱。

在没有抽象这棵‘树’之前,脑子里思考的是如何将这抹绿意搬到IDEA中。随着学习的深入,后才知道数据结构中的树 和 现实中的树其实有着一定的相似之处,却有些不同。

1:初识树?

在正式学习树这种结构之前,我先举出生活中的几个例子。

数据结构之初识树
  • 这里给出了一个非常简单的家庭关系,从奶奶辈一直到你这辈。以一种分支结构,体现了家庭关系。

  • 这是模拟公司研发部下属的一些部门,从大的研发部整个部门直到单个组。

数据结构之初识树

大家可以看着上面两张图,然后把画面倒转180°,就会发现最下面的单个节点不断向上进行发散。就像一棵真正的树,从底端的“根”,一直不断向上延伸。所以,这就是为什么将这种结构称为 ‘树’。

ps: 关于文章中出现关于节点 和 结点的问题,统一使用节点表示。

2: 树的官方定义

  • 树的定义
    树是n(n > 0)个节点的有穷集合,有以下几个特征。

    • 1、有且仅有一个称为根(root)的节点
    • 2、其他的节点分为m(m >= 0)个互相不相交的非空结合 n1,n2,n3…,这些集合每一个代表着一棵树,称为根节点的子树(有递归内味了..)

3: 树相关的名词

此部分为概念,如果有缺漏的地方,大家可以自行百度,谷歌..

  • 总览
    树由若干个节点(Node)和若干条边(edge)组成。从具体来说,树有着: 根节点(root),边(edge),父节点,子节点,叶子节点。

  • 名词介绍:

    • 如果存在两个节点node1 和 node2,存在唯一一条边连接node1,node2,且方向为 node1 -> node2,则称node1 是node2的父节点,node2是node1的子节点

    • 如果在一棵树中,每个节点最多只允许有两个子节点,称该树为 ‘二叉树(binary tree)

    • 如果不同的节点 node1,node2有着相同的父节点,则称呼node1,node2彼此为兄弟节点

    • 两个节点直接连接的线,称为’边’(edge)

    • 根节点到任何节点之间,存在着唯一的路径,路径经历的边数(可能含有权值),称为’路径的长度’

    • 根节点到达任意一个节点的路径长度,称之为该节点的‘深度’(深度是从上向下看)

    • 从某个节点的最深处叶子节点到该节点的路径长度,称为该节点的高度(高度是从下向上看)

    • 节点拥有的子树数量称为节点的度,当前树中节点度的最大值称为该树的度

tip: 为了明确上述定义,这里我将绘制一棵简单的树,同时对应着上述的定义绘制表格。

数据结构之初识树
  • 参考表格
概念名称 说明 示例
父节点 唯一路径连接的起始端 A是B的父节点
子节点 唯一路径连接的末端 B是A的子节点
兄弟节点 拥有相同父节点,位于同一级的节点 B和C
二叉树 每个节点最多拥有两个节点 当前绘制的为二叉树
两个节点直接相连的线 edge1,edge2…
路径 根节点到达某一子节点经过的边
路径长度 根节点到达某一子节点经过的边之和(注意是否累加权值) A节点为root,路径长度为0,B节点路径长度为1,D节点路径长度为2
深度 根节点到达任意一个节点的路径长度 A节点深度为0,B节点深度为1
高度 从某个节点的最深处叶子节点到该节点的路径长度 A节点高度为2,B节点高度为1
节点拥有的子树数量称为节点的度,当前树中最大节点的度称为该树的度 B节点度为2,A节点度为2,D节点度为0(叶子节点)
二叉树的度为2
  • 注: 关于深度和高度,需要看初值为多少(有些官方定义为0 有些为1)

4、树的存储形式

此处总结自<<大话数据结构>> 6.4 树的存储结构,大家在阅读之余可以去查阅原著,获得更多收获。

  • 1、双亲表示法

树在保存时,当前节点除了保存数据域,也要表示父节点的位置

数据结构之初识树



class Node{
  int val;
  Node parent = null;
  public Node(int val){
    this.val = val;
  }
}
  • 优点: 查找当前节点的父节点非常方便

  • 缺点: 查找当前节点的子节点,需要遍历整棵树,非常不方便

  • 2、孩子表示法

树在保存时,节点除了保存数据域,也要表示孩子的位置

数据结构之初识树



//这里以二叉树为例
class Node{
  int val;
  Node left = null;//左子树引用
  Node right = null;//右子树引用
  public Node(int val){
    this.val = val;    
  }
}
  • 优点: 查找当前节点的孩子节点非常方便

  • 缺点: 查找当前节点的父节点困难

  • 3、孩子兄弟表示法树在表示时候,节点除了保存数据域,也要保存孩子和当前兄弟的位置

数据结构之初识树
class Node{
  int val;
  Node firstNode;
  Node nextBro;
  public Node(int val){
    this.val = val;
  }
}
  • 优点: 可以很快查询到当前节点 和 当前节点的兄弟节点。
  • 缺点: 找寻父节点依旧很麻烦。

那有没有什么好的思路解决可以快速查询父节点和兄弟节点呢?

  • 1、在节点定义的时候将父节点 和 兄弟节点都包括进去,但是处理节点之间联系逻辑的时候会很麻烦。
  • 2、将节点之间的关系,从单向连接变成双向连接。(这部分内容会在后文中 树 和 双向链表的转换中提到,期待一下吧!!)

5、总结一下

这篇文章讲述了关于树的基础知识,其中包括对树的概念,一些基础名词,树的表示方法等,同时也是树这一系列内容的第一篇。接下来会逐渐深入,从介绍二叉树的一些内容,递归非递归遍历过渡到bst,dfs,哈夫曼编码,再到关于AVL树,B树,B+树,红黑树的具体应用等。

希望可以模拟从一个对树完全陌生的同学,逐渐去深入这一复杂的数据结构所经历的流程。那么,今天的内容就到这,我是1z,咱们下期再见吧!


往期推荐:

我们是FingerDance,欢迎加入我们!


原文始发于微信公众号(FingerDance):数据结构之初识树

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/26699.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!