数据结构与算法学习笔记(五) 树 -合毅科技
暂无图片
登录 注册
暂无图片
暂无图片
暂无图片
暂无图片

数据结构与算法学习笔记(五) 树

221

引言

上面是一颗橡树,枝繁叶茂,我们也常用枝繁叶茂来形容一个家族枝繁叶茂,原因在于树和家族之间具备共性,都是从根向外延伸,我们将树倒过来看可能体会更深一点:

如果我们我们目前主干算做根的一部分,或者说他们本就是一部分,只看枝干,那么树就可以转换为一个家族:

除了家族是一种树形结构,图书馆的分类我们也可以看做是一种树形结构,我们进入图书馆找书的时候,会先确认这本书属于哪一个分类,根据分类去对应的楼层,再根据楼层再去找他的小分类,图书馆的分类也是一种树形结构:

除此之外还有组织架构、计算机的目录结构等都属于树形结构,由此我们也就是引出了数据结构中的树。从上面的例子我们可以看出,当数据元素之间呈现的关系非一一对应,对应的关系复杂之后,线性数据结构应对这种类型的数据结构是力不从心的,我们需要一种符合树形结构特点的其他方式来描述这种呈层次关系的非线性结构。

数据结构中的树

树的基本定义和基本术语

树(tree)是包含n个结点的有限集合,其中:

  • 有一个特定结点被称为根结点或根,他只有直接后继,但没有直接前驱。
  • 除根结点之外的其余数据元素被分为m(m >= 0)个互不相交的集合T1,T2,...,Tm,其中,每一个集合Ti( 1 <= i <= m)本身也是一颗树,称为根的子树。

当树的集合为空时,n =0,此时称为空树,空树没有结点。

树是递归结构-在树的定义中又用到了树的定义,一颗非空树是由若干子树构成的,而子树又可以由更小的子树构成。

树的特点

如上图所示:

  • 每个结点都有零个或多个子结点,无子结点的结点被称为叶子结点。
  • 没有父节点的结点被称为“根结点”,规定它所在的一层为第一层。
  • 每一个非根结点有且只有一个父结点。

树常用术语的介绍

(1) 树的结点: 包含一个数据元素, 可以同时记录若干指向子树分支信息。

(2) 孩子(child) 和 父亲(parent)

种某个结点的子树之根被称为该结点的孩子或儿子,相应地,该结点称为孩子的双亲,同一个双亲的孩子被称为兄弟。

(3) 祖先(Ancestor)和子孙(Descendant)

若树中存在一个结点序列k1,k2,...,ki,...,kj使得ki是ki+1的双亲(1<=i<=j),则称该结点序列及其上的分支是从k1到kj的一条路径和道路。

路径的长度指路径所经过的边(即连接两个结点的线段)的数目,等于j - 1. 从树的根结点到树中其余结点存在一条唯一路径。

祖先和子孙: 若树中结点k到ks存在一条路径,则称k是ks的祖先,则称k是ks的祖先,ks是k的子孙。

一个结点的祖先是从根结点到该结点的路径上所经过的所有结点,而一个结点的子孙则是以该结点为根的子树中的所有结点。

约定: 结点k的祖先和子孙不包含结点k本身。

(3.1) 结点的层数(Level)和树的高度(Height)

结点的层数从根起算: 根的层数为1.其余结点的层数的等于其双亲结点的层数加1。双亲在同一层的结点互为堂兄弟。

树中结点的最大层数称为树的高度或深度。

注意,也有文献中将树根的层数定义为0。

(3.2)  结点的度(Degree)

树中的一个结点拥有的子树个数称为该结点的度。一颗树的度是指该树的结点的最大度数。下面这棵树的度就是3:

度为零的结点称为叶子(Leaf)或终端结点。度不为零的结点称为分支结点或非终端结点。度不为零的结点称分支结点或非终端结点。除根结点之外的分支结点称为内部结点。根结点又被称为开始结点。

(3.3) 有序树(OrderedTree)和无序树(UnorderedTree)

若将树中每个结点的各个子树看成从左右有次序的(即不能互换),则称该树为有序树,否则称为无序树。

注意:若不特别指明,一般讨论的树都是有序树。

(3.4) 森林(Forest)

森林是m(m >= 0)棵互不相交的树的集合。

树和森林是相关的,删去一颗树的根,就得到一个森林;反之,加上一个结点作为树根, 森林就变为一颗树。

树的逻辑结构特征

树形结构的逻辑特征可用树中结点之间的父子关系来描述。

(1) 树中的任一结点都可以有零个或多个直接后继(即孩子)结点,但至多只能有一个直接前驱(即双亲)结点。

(2) 树中只有根结点无前驱,它是开始结点,叶节点无后继,它们是终端结点。

(3) 祖先与子孙的关系是对父子关系的延拓, 它定义了树中结点之间的纵向次序。

(4) 有序树中,同一组兄弟结点从左到右有长幼之分。

对这一关系加以延拓,规定若k1和k2是兄弟,且k1在k2的左边,则k1的任一子孙都在k2的任一子孙的左边,那么就树中结点之间的横向次序。

树的存储结构

树形结构的存储,依然要遵循存储的两大原则:

  • “存数值、存联系”
  • “存得进、取的出”

由于树是非线性结构,结点间的联系的存储,要比线性结构复杂的多,根据树形结构的特点,每个结点与其直接相连的结点关系只有两类,一是双亲,二是孩子。对于一个结点而言,其双亲只有一个,孩子可以有0到n个。树形结构的存储结构设计原则,即是要实现双亲、孩子关系如何直接或间接存储。对于设计好的存储结构标准则是只要在存结构中能找到一个结点的这两种存储关系,那么这样的存储结构设计就是可行的。我们可以称之为“双亲孩子检验原则”。

同样的树的存储结构也有两种存储方式, 连续存储方式和链式存储方式。

树的连续存储方式

  1. 双亲孩子表示法

    按照“存数值,存联系”的原则,用数组存储树中结点的值,对应有下标,即结点的编号,则每个结点的双亲与孩子通过这个编号,就可以标示出来

如上图用数组来标示就下面所示:


下标结点数据双亲位置孩子位置
0A-11,2,3
1B04,5
2C06
3D07,8,9
4E1-1
5F1-1
6G2-1

代码示例:

// 这里我们先只给出一个大概的结点结构。
public class ArrayTree<T{
    private int parentIndex;
    private int[] children;
    private  T t;

    public ArrayTree() {
    }

    public int getParentIndex() {
        return parentIndex;
    }

    public void setParentIndex(int parentIndex) {
        this.parentIndex = parentIndex;
    }

    public int[] getChildren() {
        return children;
    }

    public void setChildren(int[] children) {
        this.children = children;
    }

    public T getT() {
        return t;
    }

    public void setT(T t) {
        this.t = t;
    }
}

  1. 双亲表示法

    树形结构的特点是每个结点的双亲是唯一的,我们可以从结点的是双亲关系间接得到孩子的信息,所以我们也可以只存储双亲的位置,就可以得到结点的双亲及孩子信息,所以树的连续存储方式可以简化为下面:

public class ArraySimpleTree<T>{
    private int parentIndex;
    private  T t;

    public ArraySimpleTree() {
    }

    public int getParentIndex() {
        return parentIndex;
    }

    public void setParentIndex(int parentIndex) {
        this.parentIndex = parentIndex;
    }

    public T getT() {
        return t;
    }

    public void setT(T t) {
        this.t = t;
    }
}

  1. 孩子表示法
public class ArrayChildrenTree<T{
    private int[] children;
    private  T t;

    public ArrayChildrenTree() {
    }
    public int[] getChildren() {
        return children;
    }

    public void setChildren(int[] children) {
        this.children = children;
    }

    public T getT() {
        return t;
    }

    public void setT(T t) {
        this.t = t;
    }
}

树的链式存储方式

用链表来构建树,线性链表的前驱和后继各有一个,因此线性链表存储形成的链也是直的一条,你可以理解为这个家族都是单传,那么将后继改为多个就变成了树。

  1. 孩子表示法
public class LinkedTreeNode<T{
   private T data;
   private List<LinkedTreeNode> nodes;

   public LinkedTreeNode() {
   }

   public T getData() {
      return data;
   }

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

   public List<LinkedTreeNode> getNodes() {
      return nodes;
   }

   public void setNodes(List<LinkedTreeNode> nodes) {
      this.nodes = nodes;
   }
}

  1. 孩子兄弟表示法

在存储树中每个结点时,除了包含该结点值域外,还设置两个指针域分别指向该结点的第一个孩子结点和其右兄弟,即最多只记录两个孩子的信息,这样就可以用一种统一的二叉链表的方式加以存储,因此该方法也常被称为二叉树表示法。

这种存储结构易于实现找结点孩子的等的操作,找结点的双亲不易。

public class BinaryTreeNode<T{
    private T data;
    private BinaryTreeNode rightNode;
    private BinaryTreeNode leftNode;
}

  1. 树的链式存储--孩子链表表示法

此法是树的连续存储与链式存储的组合存储方式,把每个结点的孩子结点排列起来,看成一个线性表,且以单链表为存储结构,则n个结点有n个孩子链表(叶子的孩子链表为空表)。如下图所示:

public class SequenceTree<T{
    
    private LinkedListNode<T>  nodeList;
    private T data;
    
    private class LinkedListNode<T{
        private T value;
        private LinkedListNode<T> next;
    }
}

总结

在写树这一节的时候,不想堆砌太多概念,想追随的是《C语言程序设计现代方法》的风格,在讲述每一节的时候只讲必要的概念,不堆砌,用的时候才铺陈概念,但是实践这一点似乎比较难,因为你需要对这个知识有足够了解,才能做到如此的游刃有余。但我们是无法一下子做到完美的,如果我像这样去写作,恐怕这篇文章永远发不出来。等到之后对数据结构比较熟悉之后,这部分的文章也许会重构一下。

参考资料

·《数据结构与算法分析新视角》 周幸妮 任智源 马彦卓 樊凯


文章转载自爱喝汤的技术少年,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论

相关内容推荐

关于法律的论文2000字常用论文题目sci论文润色网站植物对环境的影响论文饺子皮论文风景写生论文平庸与快乐议论文游戏作文论文论文百家姓菊与刀论文学位论文学术不端检测系统新剂型论文民法论文热点论文框架结构图论文独特性公安工作论文法学论文征文林学本科论文除法小论文脑膜瘤论文洁身自好议论文布料论文终身体育论文交通事故议论文插画艺术论文搜神记论文输入法论文生物芯片论文ahp论文山大论文抄袭si论文轮滑课论文论文人工降重多少钱金融法学论文营养早餐论文环境热点问题论文学校德育论文方法形论文本专科论文钢筋混凝土结构论文经管论文选题建筑审美论文乐府诗论文网络安全论文3000毕业论文要双面打印吗校内网论文教育投资论文税务类论文谦让议论文素材航海学论文土壤修复论文经济论文1000字铭记历史开创未来论文论文检测要求找准方向的议论文小吃街论文电工专业论文玩耍议论文组合结构论文购论文集科技论文分区岗培小论文期刊论文的结构有电大论文抄袭合同法论文选题龙游 论文论文引言写法议论文病文网络流论文论文打分表体育类论文发表日式餐厅论文摊铺机论文传染病的预防与控制论文自尊自爱议论文茶餐厅论文电气工程及自动化毕业论文山东大学学位论文规范如何答议论文综述论文要求关于文明的高中议论文协整论文图像学论文趣味识字论文毕业论文纲要营销专业毕业论文范文好论文的特点丛飞议论文人物雕塑论文生物论文结尾生态类论文安全带论文夏目漱石心论文除四害论文地理论文摘要voip论文论文列提纲论文代理网中文系论文题目论文明班级论文实践题善与恶作文议论文中式烹饪论文自考毕业论文查重吗齐文化论文监理论文题目自动焊论文关于积累的800议论文论文降重招聘代客扫墓议论文个人信贷论文输血医学论文汗症的论文资产定价论文女权议论文信源编码论文精调论文论文部分抄袭云南教育论文发表法的价值论文刑法硕士论文杜鹃花论文电压测量论文论文自评范文雕刻艺术论文板块运动论文我的信仰论文激励小论文失去后才知道可贵议论文论文降重的兼职名著论文怎么写经济学研究生毕业论文关于法治建设的论文反假货币论文创造型论文医学生物学论文高压毕业论文中文论文文内引用格式调节阀论文发言议论文祸患积于忽微的议论文会计博士论文西藏大学论文钢的热处理论文小学艺术教育论文动漫设计毕业论文3000农业水利工程论文审计论文大纲体育学士论文应激与健康论文名家议论文赏析敢为天下先800字议论文管理文秘论文博士论文绪论海洋地质论文小综述论文龙鱼论文不端学术论文检测报答议论文环保与发展的议论文墙体裂缝论文论文投稿地址晶体材料论文人性的光辉议论文教师节论文论文多的网站虎妞论文营养减肥论文琅琊山论文谷物的论文p2p风险论文宫颈炎论文本论文英文开卷有益议论文600农经师论文新型城镇化建设论文aaa论文职场关键能力论文参考文献如何写学位论文反手论文蚜虫 论文党建论文题目航空业论文光明乳业论文扬长避短议论文800腊梅议论文论文上哪找万方论文网站品牌故事论文游戏作文论文马术论文扶老人论文地形测绘论文教学德育论文路政执法论文数学与应用数学专业导论论文议论文扣题电影赏析论文怎么写非攻议论文药品收货与验收论文

合作伙伴

合毅科技

www.clhczx.cn
www.xtcwl.com
seo.jsfengchao.com
www.28j.com.cn
www.tjwyj.com
www.3phw.com
www.3phw.com
www.te3.com.cn
idc.urkeji.com
seo.07yue.com
www.wangluohr.cn
www.conductive-powder.com
www.pifajia.net.cn
seo.chaoshanxing.com
www.3phw.com
idc.urkeji.com
seo.07yue.com
www.tjwyj.com
zz1.urkeji.com
www.urkeji.com