4.0 树

本文详细介绍了树的数据结构,包括树的定义、术语、表示方法和抽象数据类型。树由结点组成,每个结点有度,度为0的结点称为叶子结点,非叶子结点称为分支结点。树的层次由根结点开始逐层展开,高度为最远结点的层次。树的表示方式有图示法、嵌套集合表示法和凹入表示法。此外,还讨论了树的存储结构,包括双亲表示法、孩子表示法和孩子兄弟表示法。最后,提到了树的常见操作,如遍历、插入和删除。
摘要由CSDN通过智能技术生成

学习总结

4.1.1树的定义


        树(Tree)是n(n≥0)个结点的有限集T。T为空时,称为空树。T非空时,满足以下两个约定条件:
        ①有且仅有一个特定的称为根(Root)的结点。
        ②其余的结点可分为m(m≥0)个互不相交的有限子集 T,T2,…,Tmo其中每个子集本身又是一棵树,并称其为根的子树(SubTree)。
        树是递归定义的。结点是树的基本单位,若干个结点组成一棵子树,若干棵互不相交的子树组成一棵树。树中的每一个结点都是该树中某一棵子树的根。因此,树是由结点组成且结点之间具有层次关系的非线性结构。空树、只有根结点的树以及有多个结点的树如图4-2所示。

4.1.2树的术语

1.结点


        结点是包含一个数据元素及指向其若干子树的分支,在树的图形表示中为一个圆圈。结点的前驱结点称为其父母(Parent)结点,后继结点称为其孩子(Child)结点。一棵树中只有根结点没有父母结点,其他结点有且仅有一个父母结点。拥有同一个父母结点的多个结点相互称为兄弟(Sibling)结点。
        结点的祖先(Ancestor)是指其父母结点以及父母的父母结点等,直至根结点。结点的后代(Descendant,也称子孙)是指其所有孩子结点,以及孩子的孩子结点等。

2.度


        结点的度(Degree)是结点所拥有的子树的数量。度为0的结点称为叶子结点(Leaf),又称为终端结点:树中除叶子结点之外的其他结点称为分支结点,又称为非终端结点。树的度是树中各结点的度的最大值。


3.结点层次、树的高度


        结点的层次(Level)反映结点在树中的层次位置,约定根结点的层次为1,其余结点的层次等于其父母结点的层次加1。显然,兄弟结点层次相同。树的高度(Height)或深度(Depth)是指树中各结点的层次最大值。

 4.边、路径


设树中X结点是Y结点的父母结点,有序对(X,Y)称为连接这两个结点的分支,也称为边。

5.无序树、有序树


        在树的定义中,结点的子树 To,T,T,…,Tm-1之间没有次序,可以交换位置,称为无序树。如果结点的子树To,T,T,…,Tm-,从左到右是有次序的,不能交换位置,则称为有序树。


 

 6.森林


        森林(Forest)是m(m≥0)棵互不相交的树的集合。对树中的每一个结点而言,其子树的集合即为森林。可以通过森林与树相互递归的定义来描述树。

 4.1.3 树的表示

1.图示法


        结点用圆圈表示,结点名字写在圆圈旁或圆圈内,子树与其根之间用无向边来连接。图4-5是图示法表示的树。

2.嵌套集合表示法


用集合的包含关系描述树结构,可以使用图4-6所示的树的嵌套集合表示。


 

 

3.凹入表示法


类似于书的目录,使用线段的伸缩描述树结构。

4.1.4 树的抽象数据类型


        树的操作主要有创建树、获取父母/孩子/兄弟结点、遍历、插入和删除等。描述树抽象数据类型的Java接口声明如下,其中T为结点的元素类型,TreeNode
为树结点类。

//树抽象数据类型,T表示数据元素的数据类型
public interface TTree<T>{
    public boolean isEmpty();//判断是否空树
    /!返回树的结点个数
    public int count ();
    public int height ();
    //返回树的高度
    public int childCount (TreeNode<T> p);//返回p结点的孩子结点个数
    publicvoid preorder (;
    //先序遍历树
    publicvoid postorder();//后序遍历树
    public void levelorder(; //层次遍历树//返回p结点的第                                                                                    
    i(i>=0)个孩子结点
    public Treelode<T> getchild(TreeNode<T> p,int i);//返回p结点的最后一个孩子结点
    public TreeNode<T>getLastchild(TreeNode<T> p);//返回p结点的最后一个兄弟结点
    public TreeNode<T>getLastsibling(TreeNode<T>p);
    public TreeNode<T>getParent (TreeNode<T> node);/*返回 node
    的父结点*/
    public TreeNode<T> search(T x);//查找并返回元素为x的结点
    public void insertRoot (T x);//插入元素×作为根结点//插入×元素作为p结点的第i个孩子
    public TreeNode<T> insertChild (TreeNode<T> p,T x, int i);//插入最后一个孩子结点
    public TreeNode<T> insertLastChild (TreeNode<T> p,T x);//插入最后一个兄弟结点
    public TreeNode<T> insertLastSibling(TreeNode<T> P,Tx);//删除以p结点的第i个孩子为根的子树
    publicvoid removeChild(TreeNode<T>p, int i);
    publicvoid removeAll(); //删除树
}


 

 其中,树的结点类声明如下:

//树的结点类
public class TreeNode<T>{
    public T data;
    //数据域,存储数据元素
    public TreeNode<T>child;//孩子结点
    public TreeNode<r> sibling;//兄弟结点
    public TreeNode(Tdata, TreeNode<T> child,TreeNode<T>sibling)
    this.data=data;
    this.child=child;
    this.sibling-sibling;
    public TreeNode(T data){
    this(data, null, null);//构造指定值的叶子结点
    public T上eeNode({
    this (null,null,null)://空树
    }
}

4.1.5树的存储结构


        树中某个结点的孩子可以有多个,这就意味着,无论用哪种顺序将树中所有的结点存储到数组中,结点的存储位置都无法直接反映其逻辑关系。试想一下,数据元素挨个存储,那么谁是谁的双亲,谁又是谁的孩子呢?所以简单的顺序存储是不能满足树的实现要求的。
        可以充分利用顺序存储结构和链式存储结构的特点,实现对树的存储结构的表示。下面介绍3种不同的树的表示法:双亲表示法、孩子表示法、孩子兄弟表示法。


1.双亲表示法


        假设以一组连续空间存储树的结点,同时在每个结点中附设一个指示器,指向其双亲结点到链表中的位置。也就是说,每个结点除了知道自己之外还需要知
道它的双亲在哪里。

 

 2.孩子表示法


        把每个结点的孩子结点排列起来,以单链表作为存储结构,则n个结点有n个孩子链表。如果是叶子结点,则此单链表为空。n个头指针又组成一个线性表,
采用顺序存储结构,存放进一个一维数组中。孩子表示法如图4-10所示。

 

 3.孩子兄弟表示法


        任意一棵树,它的结点的第一个孩子如果存在就是唯一的,它的右兄弟存在也是唯一的。因此,设置两个指针,分别指向该结点的第一个孩子和此结点的右兄弟。
孩子兄弟表示法的结点结构见表4-3。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值