来源:互联网 发布:淘宝最迟几天发货 编辑:程序博客网 时间:2024/05/16 12:28

1.基本概念

树:是n(n>=0)个结点的有限集。在任意一颗非空树种:(1)有且仅有一个特定的称为根的结点;(2)当n>1时,其余结点可分为m(m>0)个互不相交的有限集T1,T2....Tn,其中每一个集合本身又是一棵树,并且称为根的子树。

度:结点拥有的子树数。

叶节点/终端结点:度为0的结点。

分支结点/非终端结点:度非0的结点。

树的度:结点度的最大值。

树的深度/高度:树中结点的最大层次。

有序树/无序树:树中各节点的各子树从左至右,不能互换的树。否则为无序树。

森林:若干棵互不相交的树的集合。

2.抽象数据类型(ADT)

数据对象:由若干相同数据类型的结点组成的集合

数据关系:由一个根结点和若干子树组成。根节点无前驱,结点下的子树互不相交,任何一棵子树又称为根的子树。

基本操作:

                  InitTree(*T): 构造空树T。

                  DestroyTree(*T): 销毁树T。

                  CreateTree(*T, definition): 按definition构造树T。

                  ClearTree(*T): 清空树。

                  TreeEmpty(T): 验证树是否为空。

                  TreeDepth(T): 返回树的深度。

                  Root(T): 返回树的根结点。

                  Value(T, cur_e): cur_e是树中的一个结点,返回此结点的值。

                  Assign(T,cur_e,value): 将结点cur_e赋值给value。

                  Parent(T,cur_e): 若cur_e不是根节点,则返回结点cur_e的双亲,否则返回空。

                  LeftChild(T,cur_e): 若结点cur_e非叶结点,则返回结点的左孩子,否则返回空。

                  RightSibling(T,cur_e): 若结点cur_e有右兄弟,则返回结点的右兄弟,否则返回空。

                   InsertChild(*T,*p,i,c): 插入c为树T中p指结点的第i棵子树(c与T不相交,1<=i<=所指结点度+1)

                  DeleteChild(*T,*p,i): 删除树T中p指结点的第i棵子树(1<=i<=所指结点度)。

3.树的存储结构

树的存储结构包括双亲表示法孩子表示法孩子兄弟表示法。他们都是常用的链表结构。

双亲表示法

在每个结点中附设一个指示器指示双亲结点在链表中的位置。

 //树的双亲存储结构定义#define MAXTREESIZE 100    typedef int ElemType;         //元素的数据类型根据实际情况而定,这里假设为int   typedef struct Node          //结点结构 {      ElemType data;            //数据域,用于存储结点数据       int    parrnt;           //双亲位置                }PTNode;typedef struct{PTNode nodes[MAXTREESIZE];   //用数组来存储结点 int r,n;                    //r为根节点的位置,n为结点个数 }PTree;
在这种存储方法中,根节点的双亲位置为-1,其余结点的双亲位置为其双亲在数组中的下标。使用这种方法可以快速地找到结点的双亲。但是若要寻找某结点的孩子,则需要遍历整个结构,对此极为不方便。我们可以增加一个左孩子域。若需要寻找结点的兄弟,则可以增加一个右兄弟域。根据对应的需求增加对应的域。

孩子表示法

将每个结点的孩子结点排列起来,以单链表作为存储结构。n个结点就有n个孩子链表,终端结点的孩子链表为空。每个结点及其对应的孩子链表组成一个线性表,采用顺序存储结构,放进数组中。

//树的孩子存储结构 typedef struct Childnode      //孩子链表中结点结构 {int   Child;             //该孩子结点在数组中的下标 struct Childnode *next;  //指针,指向下一个孩子结点 }*Childnodes;typedef struct Node          //顺序存储结构中的结点结构 {ElemType     data;       //结点数据 Childnodes   firstchild;  //该结点对应的孩子链表的头指针   }PTNode;typedef struct              //树结构 {PTNode nodes[MAXTREESIZE];  //用数组来存储结点int r,n;                    //r为根节点的位置,n为结点个数}PTree;

这样寻找某结点某个孩子或兄弟,只需要遍历对应的孩子链表即可。但是寻找双亲则需要遍历整颗树,因此我们可以结合双亲表示法和孩子表示法,添加一个双亲域,这样的方法称为双亲孩子表示法。改动非常小:

typedef struct Node          //顺序存储结构中的结点结构 {ElemType     data;       //结点数据 Childnodes   firstchild;  //该结点对应的孩子链表的头指针int    parrnt;           //双亲位置    }PTNode;

孩子兄弟表示法

在每个结点中设置两个指针域,分别指向该节点的第一个孩子(左孩子)和此结点的右兄弟。

//树的孩子兄弟存储结构typedef struct Node          //结点结构 {      ElemType      data;           //数据域,用于存储结点数据       struct Node  *firstchild;     //指针,指向该结点的第一个孩子     struct Node  *rightsib;   //指针,指向该结点第一个右兄弟             }CSNode,*CSTree;
该方法又称二叉树表示法或二叉链表表示法,此方法将普通的树转换为二叉树,因此可以利用二叉树的特性和算法来处理这棵树。





原创粉丝点击