数据结构-基本概念简介

基础概念

大家都知道,数据结构是计算机存储、组织数据的方式。

它研究的是数据的逻辑结构和数据的物理结构以及它们之间的相互关系,并对这种结构定义相适应的运算,设计出相应的算法,并确保经过这些运算以后所得到的新结构仍保持原来的结构类型。简而言之,数据结构是相互之间存在一种或多种特定关系的数据元素的集合,即带“结构”的数据元素的集合。“结构”就是指数据元素之间存在的关系,分为逻辑结构和存储结构。

存储结构也即数据的物理结构.

存储结构

存储结构分为顺序存储、链式存储、索引存储和散列存储。

顺序存储

把逻辑上相邻的元素储存在物理位置上也相邻位置的储存单元里面,元素之间的关系由相关存储单元之间的邻接关系来体现。

其优点是可以实现随机存取,每个元素占用最少的存储空间
相应的缺点是只能使用相邻的一整块的存储单元,因此可能造成较多的外部碎片

链接存储

不要求逻辑上相邻的元素在物理位置上也相邻,借助指示元素存储地址的指针表示元素之间的逻辑关系。

其优点是不会产生碎片,充分利用了存储单元;
缺点是每个元素因为存储指针而占用了额外的存储空间,并且只能实现顺序存储

索引存储

在储存元素信息的同时,还建立了额外索引表。索引表中的每一项称为索引项
索引项的一般形式是**(关键字,地址)**。

优点是检索速度快
缺点是因为建立了额外的索引表,占用了较多的存储空间,除此之外,在对数据进行增删的时候要修改索引表,会花费较多的时间.

散列存储

散列存储根据元素的关键字直接计算出该元素的存储位置,又称Hash存储

优点是检索、增加和删除节点都很快
缺点是如果散列函数不好可能出现元素存储单元的冲突,而解决冲突又会增加时间和空间的开销。

逻辑结构

线性表

根据存储方式有顺序存储和链式存储

顺序存储:顺序表
链式存储又分为:单链表、双链表、循环链表和静态链表(借助数组实现)

栈和队列

栈的图示:
在这里插入图片描述
在这里插入图片描述
队列图示:
在这里插入图片描述
栈和队列,严格意义上来说,也属于线性表,因为它们也都用于存储逻辑关系为 “一对一” 的数据.

使用栈结构存储数据,讲究“先进后出”,即最先进栈的数据,最后出栈;
使用队列存储数据,讲究"先进先出",即最先进队列的数据,也最先出队列。

栈分为顺序栈、链栈和共享栈
对列分为循环队列(顺序存储、数组实现)、链式队列和双端队列

在这里插入图片描述

存储结构分为双亲表示法、孩子表示法和孩子兄弟表示法

双亲表示法

取一块连续的内存空间,在存储每个结点的同时,各自都附加一个记录其父结点位置的变量

#define tree_size 100//宏定义树中结点的最大数量
#define TElemType int//宏定义树结构中数据类型TElemType 即为int
typedef struct PTNode{ //结点结构
    TElemType data;
    int parent;     //双亲位置域
}PTNode;
typedef struct {   //树结构
    PTNode nodes[tree_size];//存放树中所有结点
    int r,n;//根的位置和结点数
}PTree;

孩子表示法

将树中的每个结点的孩子结点排列成一个线性表,用链表存储起来。对于含有 n 个结点的树来说,就会有 n 个单链表,将 n 个单链表的头指针存储在一个线性表中,这样的表示方法就是孩子表示法。

#define TElemType int  //同上进行宏定义
#define Tree_Size 100
typedef struct CTNode{   //孩子结点
    int child;//链表中每个结点存储的不是数据本身,而是数据在数组中存储的位置下标
    struct CTNode * next;
}*ChildPtr;
typedef struct {
    TElemType data;//结点的数据类型
    ChildPtr firstchild;//孩子链表的头指针
}CTBox;
typedef struct{
    CTBox nodes[Tree_Size];//存储结点的数组
    int n,r;//结点数量和树根的位置
}CTree;

孩子兄弟表示法

使用链式存储结构存储普通树。链表中每个结点由 3 部分组成:孩子指针域、数据域和兄弟指针域
其中孩子指针域,表示指向当前结点的第一个孩子结点,兄弟结点表示指向当前结点的下一个兄弟结点。

#define ElemType int
typedef struct CSNode{
    ElemType data;
    struct CSNode * firstchild,*nextsibling;
}CSNode,*CSTree;

二叉树分为顺序存储结构和链式存储结构

邻接矩阵、邻接表、十字链表和邻接多重表
邻接表、十字链表和邻接多重表都是按照链表的方式存储的。

邻接矩阵

百度百科解释如下:

逻辑结构分为两部分:V和E集合,其中,V是顶点,E是边。因此,用一个一维数组存放图中所有顶点数据;用一个二维数组存放顶点间关系(边或弧)的数据,这个二维数组称为邻接矩阵。邻接矩阵又分为有向图邻接矩阵和无向图邻接矩阵

邻接矩阵(Adjacency Matrix)是表示顶点之间相邻关系的矩阵。设G=(V,E)是一个图,其中V={v1,v2,…,vn} [1] 。G的邻接矩阵是一个具有下列性质的n阶方阵:
①对无向图而言,邻接矩阵一定是对称的,而且主对角线一定为零(在此仅讨论无向简单图),副对角线不一定为0,有向图则不一定如此。
②在无向图中,任一顶点i的度为第i列(或第i行)所有非零元素的个数,在有向图中顶点i的出度为第i行所有非零元素的个数,而入度为第i列所有非零元素的个数。
③用邻接矩阵法表示图共需要n^2个空间,由于无向图的邻接矩阵一定具有对称关系,所以扣除对角线为零外,仅需要存储上三角形或下三角形的数据即可,因此仅需要n(n-1)/2个空间。

邻接矩阵它的空间和时间复杂度都是N2

邻接表

图的邻接表存储方法跟树的孩子链表示法相类似,是一种顺序分配和链式分配相结合的存储结构。如这个表头结点所对应的顶点存在相邻顶点,则把相邻顶点依次存放于表头结点所指向的单向链表中。如词条概念图所示,表结点存放的是邻接顶点在数组中的索引。对于无向图来说,使用邻接表进行存储也会出现数据冗余,表头结点A所指链表中存在一个指向C的表结点的同时,表头结点C所指链表也会存在一个指向A的表结点。 [1]
邻接表是图的一种最主要存储结构,用来描述图上的每一个点。对图的每个顶点建立一个容器(n个顶点建立n个容器),第i个容器中的结点包含顶点Vi的所有邻接顶点。实际上我们常用的邻接矩阵就是一种未离散化每个点的边集的邻接表。
在有向图中,描述每个点向别的节点连的边(点a->点b这种情况)。
在无向图中,描述每个点所有的边(点a-点b这种情况)
与邻接表相对应的存图方式叫做边集表,这种方法用一个容器存储所有的边。
在这里插入图片描述

十字链表

十字链表(Orthogonal List)是有向图的另一种链式存储结构。该结构可以看成是将有向图的邻接表和逆邻接表结合起来得到的。用十字链表来存储有向图,可以达到高效的存取效果。同时,代码的可读性也会得到提升。

邻接多重表

邻接多重表仅适用于存储无向图或无向网。

邻接多重表存储无向图的方式,可看作是邻接表和十字链表的结合。同邻接表和十字链表存储图的方法相同,都是独自为图中各顶点建立一张链表,存储各顶点的节点作为各链表的首元节点,同时为了便于管理将各个首元节点存储到一个数组中。

资料来源

什么是栈,栈存储结构详解
数据结构之树
树的双亲表示法、孩子表示法和孩子兄弟表示法

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值