数据结构(四)树---树的存储结构

前提

树中的某个结点的孩子可以有多个,所以仅仅使用简单的顺序结构或者链式结构是不能完全表示一整棵树的。
充分利用顺序存储结构和链式存储结构的特点,完全可以实现对树的存储结构的表示
我们表示一棵树的方法有:双亲表示法,孩子表示法,孩子兄弟表示法

补充

对于双亲表示法:我们先将双亲结点存入,我们每插入一个结点都是知道双亲结点位置的,数据可以直接插入。使用顺序存储结构更加方便
而对于孩子表示法,我们每次插入一个结点,对其子树的位置存放暂不确定,所有使用链式存储结构占主要

(一)双亲表示法

以双亲作为索引的关键词的一种存储方式
每个结点只有一个双亲,所以选择顺序存储占主要
以一组连续空间存储树的结点,同时在每个结点中,附设一个指示其双亲结点位置的指针域

1.结点结构

2.结点结构定义

/*树的双亲表示法结点结构定义*/
#define MAX_TREE_SIZE 100

typedef int TElemType;

typedef struct PTNode    //结点结构
{
    TElemType data;    //结点数据
    int parent;        //双亲位置
}PTNode;

typedef struct //树结构
{
    PTNode nodes[MAX_TREE_SIZE];    //结点数组
    int r, n;    //r是根位置,n是结点数
}PTree;

3.优缺点分析

优点:parent指针域指向数组下标,所以找双亲结点的时间复杂度为O(1),向上一直找到根节点也快
缺点:由上向下找就十分慢,若要找结点的孩子或者兄弟,要遍历整个树

4.改进一:方便获取孩子结点

在双亲结点基础上加入孩子结点位置,由于可能一个结点有多个子树,所以我们要根据数的度来设置添加几个孩子结点的元素

树的度为3,所以我们在结点结构设置上添加3个指针域,指向孩子结点,若是孩子为空则位置为-1
/*树的双亲表示法结点结构定义*/
#define MAX_TREE_SIZE 100

typedef int TElemType;

typedef struct PTNode    //结点结构
{
    TElemType data;    //结点数据
    int parent;        //双亲位置
    int child1;        //孩子结点1
    int child2;        //孩子结点2
    int child3;        //孩子结点3
}PTNode;

typedef struct //树结构
{
    PTNode nodes[MAX_TREE_SIZE];    //结点数组
    int r, n;    //r是根位置,n是结点数
}PTree;

缺点:这样消耗了大量的空间,是不必要的,

我们尽可能使用较小的空间,所以我们一般只添加一个长子域,可以获取到有0个或1个孩子结点,甚至两个子树都可以获取,但是对于较多的孩子我们若是非得使用顺序存储,就得使用上面方法。

注意:长子域是最左边孩子的域

/*树的双亲表示法结点结构定义*/
#define MAX_TREE_SIZE 100

typedef int TElemType;

typedef struct PTNode    //结点结构
{
    TElemType data;    //结点数据
    int parent;        //双亲位置
    int firstchild;    //长子域
}PTNode;

typedef struct //树结构
{
    PTNode nodes[MAX_TREE_SIZE];    //结点数组
    int r, n;    //r是根位置,n是结点数
}PTree;

5.改进二:方便获取各兄弟之间的关系

我们只需要增加一个有兄弟域,即可依次获取所有的兄弟结点
/*树的双亲表示法结点结构定义*/
#define MAX_TREE_SIZE 100

typedef int TElemType;

typedef struct PTNode    //结点结构
{
    TElemType data;    //结点数据
    int parent;        //双亲位置
    int rightsib;    //右兄弟结点
}PTNode;

typedef struct //树结构
{
    PTNode nodes[MAX_TREE_SIZE];    //结点数组
    int r, n;    //r是根位置,n是结点数
}PTree;

总结:

存储结构的设计是一个十分灵活的过程。一个存储结构设计是否合理,取决于基于该存储结构的运算是否合适,方便,时间复杂度好不好等。
例如若是我们既关注孩子又关注兄弟,而且对时间遍历要求高,那么我们可以扩展上面结构含有双亲域,长子域,右兄弟域

(二)孩子表示法(主要关注孩子结点)

由于每个结点可有多个子树(无法确定子树个数),可以考虑使用多重链表来实现。

根据树的度来设置孩子域的个数,例如本例中度为3,设置3个孩子域
/*树的孩子表示法结点结构定义*/
#define MAX_TREE_SIZE 100

typedef int TElemType;

typedef struct PTNode    //结点结构
{
    TElemType data;    //结点数据
    int child1;    //孩子1结点
    int child2;    //孩子2结点
    int child3;    //孩子3结点
}PTNode;

typedef struct //树结构
{
    PTNode nodes[MAX_TREE_SIZE];    //结点数组
    int r, n;    //r是根位置,n是结点数
}PTree;

缺点:占用了大量不必要的孩子域空指针

改进一:为每个结点添加一个结点度域,方便控制指针域的个数

缺点:维护困难,不易实现

改进三:结合顺序结构和链式结构

/*树的孩子表示法结点结构定义*/
#define MAX_TREE_SIZE 100

typedef int TElemType;

typedef struct CTNode    //孩子结点
{
    int child;
    struct CTNode* next;
}*ChildPtr;

typedef struct    //表头结构
{
    TElemType data;
    ChildPtr firstChild;  //这里只是一个头指针,指向第一个结点
}CTBox;

typedef struct //树结构
{
    CTBox nodes[MAX_TREE_SIZE];    //结点数组
    int r, n;    //r是根位置,n是结点数
}CTree;

改进四:添加双亲域,方便查找双亲结点(双亲孩子表示法)

/*树的孩子表示法结点结构定义*/
#define MAX_TREE_SIZE 100

typedef int TElemType;

typedef struct CTNode    //孩子结点
{
    int child;
    struct CTNode* next;
}*ChildPtr;

typedef struct    //表头结构
{
    TElemType data;
    int parent;
    ChildPtr firstChild;    //指向第一个孩子的指针
}CTBox;

typedef struct //树结构
{
    CTBox nodes[MAX_TREE_SIZE];    //结点数组
    int r, n;    //r是根位置,n是结点数
}CTree;

(三)孩子兄弟表示法

上面从双亲,孩子角度研究树的结构,下面我们从树的结点的兄弟角度来研究
任意一棵树,他的结点的第一个孩子如果存在就是唯一结点,他的右兄弟如果存在,也是唯一的,因此,我们设置两个指针,分别指向该结点的第一个孩子和该结点的右兄弟

typedef int TElemType;

typedef struct CSNode
{
    TElemType data;
    struct CSNode* firstchild, *rightsib;
}CSNode,*CSTree;
若有需要,可以再加入一个双亲域,但是上面的结构以及转换为二叉树,我们可以使用二叉树的一系列方法,来解决问题

原文地址:https://www.cnblogs.com/ssyfj/p/9459887.html

时间: 2024-07-31 17:19:50

数据结构(四)树---树的存储结构的相关文章

数据结构--二叉树(定义与存储结构)

什么是二叉树 是具有n个节点的有限集合,由一个根节点和两棵互不相交二叉树组成.如图 从名字简单理解,就是具有2个树叉的树形结构,当然这不是绝对的,正如上图所示,我也可以只有一个树叉. 二叉树具有五种基本形态: (1)空二叉树 (2)只有一个根结点的二叉树 (3)只有左子树 (4)只有右子树 (5)既有左子树又有右子树 完全二叉树 这种二叉树,是二叉树中常用的专业术语,不是说一个完整的二叉树就是完全二叉树,这种二叉树叫满二叉树,如图 简单理解就像图片中,完全二叉树中每个节点的编号,都能映射到满二叉

数据结构所涉及的数据存储结构类型

大类分别为: 线性表,栈,队列,树,二叉树,图 线性表: 顺序存储结构的定义 typedef struct { ElemType data[maxsize];            //存放顺序表中的元素 int length;                       //存放顺序表的长度 }SqList;                     //顺序表的类型定义 链式存储结构的定义 typedef struct LNode             //定义单链表的节点类型 { Elem

1、数据结构的基本逻辑结构、存储结构和运算

数据结构的基本逻辑结构.存储结构和运算 1.基本逻辑结构 集合结构.线性结构.树形结构和图状结构 2.基本存储结构 线性存储:需要一块连续的内存地址空间,相关元素一次存储 链接存储:不需要连续的地址空间,每个节点包含元素和链接两个部分,元素存储数据值,链接存储下一个节点的地址 3.基本运算 ·创建运算 ·清除运算 ·插入运算 ·搜索运算(根据值返回位置) ·更新运算 ·访问运算(根据位置返回值) ·遍历运算 1.数据结构的基本逻辑结构.存储结构和运算,布布扣,bubuko.com

数据结构--图的定义和存储结构

图的定义 图(Graph)是由顶点的有穷非空集合和顶点之间边的集合组成.注意:在图结构中,不允许没有顶点,在定义中,如果V是顶点的集合,则强调了顶点集合V的有穷非空. 在图中,若不存在顶点到其自身的边,且同一条边不重复出现,则称这样的图为简单图. 图的存储结构 邻接矩阵 考虑到图是由顶点和边或者弧两部分组成的.合在一起比较困难,那就自然地考虑到分两个结构来分别存储.顶点不分大小.主次,所以用一个一位数组来存储是很不错的选择.而边或者弧是顶点与顶点之间的关系,一维搞不定,那就考虑用一个二维数组来存

数据结构基础(20) --图的存储结构

图的结构定义 图是由一个顶点集 V 和一个弧集 E构成的数据结构. Graph = (V , E ) 其中,E = {<v,w>| v,w∈V 且 P(v,w)} <v,w>表示从 v 到 w 的一条弧,并称 v 为弧尾,w 为弧头.谓词 P(v,w) 定义了弧 <v,w>的意义或信息. 由顶点集和边集构成的图称作无向图. 如果"弧"是有方向的,则称由顶点集和弧集构成的图为有向图. 邻接矩阵 定义:矩阵的元素为 有向图的邻接矩阵为非对称矩阵, 而无向

【C语言--数据结构】线性表链式存储结构

直接贴代码 头文件 #ifndef __LINKLIST_H__ #define __LINKLIST_H__ typedef void LinkList; typedef struct _tag_LinkListNode { LinkList* next; }LinkListNode; LinkList* LinkList_create(); void LinkList_Destroy(LinkList* pstList); void LinkList_Clear(LinkList* pstL

数据结构之队列——链式存储结构(php代码实现)

<?php class QNode{     public  $data;     public  $next;     public function __construct($data){         $this->data=$data;         $this->next=null;     } } class LinkQueue{ //链队列包含头结点,实例化时,此队列为空     private $data;     private $next;     private

数据结构之栈——链式存储结构(php代码实现)

<?php /**     1. DestroyStack(): 栈的销毁     2. ClearStack(): 将栈置为空栈     3. StackEmpty(): 判断栈是否为空     4. StackLength(): 返回栈的长度     5. GetTop(): 取得栈顶的元素     6. Push(): 插入新的栈顶元素     7. Pop(): 删除栈顶元素     8. StackTraverse(): 遍历栈元素  */ class LNode{     publi

数据结构习题之树

                                   第六章 树 一.基本要求.重点.难点 本章目的是介绍二叉树的定义.性质.存储结构.遍历.树的定义.存储结构.遍历.树和森林与二叉树的转换,哈夫曼树等内容. 本章重点是掌握二叉树的遍历算法及有关应用.难点是使用本章所学到的有关知识设计出有效算法,解决与树或二叉树相关的应用问题. 二.考核目标.考核要求 1.树的概念,要求达到"理解"层次 1.1树的逻辑结构特征. 1.2树的不同表示方法. 1.3树的经常使用术语及含义.

数据结构(五)图---图的存储结构5种

一:图的抽象数据类型 ADT 图(Graph) Data 顶点的有穷非空集合和边的集合 Operation CreateGraph(*G,V,VR):按照顶点集V和边弧集VR的定义构造图G DestroyGraph(*G):图G存在则销毁 LocateVex(G,u):若图G中存在顶点u,则返回图中位置 GetVex(G,v):返回图中顶点v的值 PutVex(G,v,value):将图G中顶点v赋值给value FirstAdjVex(G,*v):返回顶点v的一个邻接顶点,若顶点在G中无邻接顶