精华内容
下载资源
问答
  • 常见的存储结构及其优缺点

    千次阅读 2020-03-24 01:29:47
    逻辑关系映射到物理存储映射方式有4种:顺序、链式、索引、哈希,相应地就产生了四种存储结构:顺序存储结构、链式存储结构、索引存储结构、哈希存储结构。 顺序存储 特点:存储空间地址连续,数据元素依次存放...

    逻辑关系映射到物理存储的映射方式有4种:顺序、链式、索引、哈希,相应地就产生了四种存储结构:顺序存储结构、链式存储结构、索引存储结构、哈希存储结构

    顺序存储

    • 特点:存储空间的地址连续,数据元素依次存放;利用物理相邻表示(存储)逻辑关系。
    • 优点:存储密度大;可以随机访问,在O(1)内查询、修改元素。
    • 缺点:表示关系能力弱;维护关系困难(逻辑关系发生变化,物理上难同步),在O(n)内插入和删除数据;存储空间必须一次获得(适用性差)。

    链式存储

    • 特点: 占用空间任意,元素任意存放;在存放元素的同时,还存放与其有关系的元素的地址(指针)。
    • 优点:空间任意;显式地存储关系;表示关系的能力强;在O(1)内插入、删除元素(只需改变结点的指针),便于动态管理内存。
    • 缺点:空间开销大,占用空间较多,存储密度小;必须通过指针来访问元素,在O(n)内查找、修改元素。

    索引存储

    • 特点:存储空间是多段连续空间,在存储结点信息的同时,还建立附加的索引表,索引表由若干索引项组成。
    • 优点:顺序和链式结合;数据检索速度快,保证数据的唯一性。
    • 缺点:创建索引和维护索引需要时间,而且索引也会占用一定的物理空间;对数据增删查改的同时也要对索引进行维护。

    哈希存储

    • 特点:又称散列存储,数据元素的存储位置和关键码(在数据结构中,指的是数据元素中能起标识作用的数据项)之间有着确定对应关系,其基本思想是由结点的关键码值决定结点的存储地址,除了用于查找外还可以用于存储,存储空间是连续空间。(有的HASH函数为取模函数)
    • 优点:利用数据的某一特征访问和存储,访问速度快,在O(1)内遍历元素。
    • 缺点:好的HASH很难;有时会产生冲突。
    展开全文
  • 的常见存储结构

    2020-01-30 16:29:43
    的存储结构 邻接矩阵 邻接矩阵的表示方式为一个拥有两个维度的数组。其表示方法为 define N 1000+5 int a[N][N] a[i][j]=1;//其从i到j有边,其权值为1。一般当图是没有权重的 //就视为其权重为1 前向星 前...

    图的存储结构

    邻接矩阵

    邻接矩阵的表示方式为一个拥有两个维度的数组。其表示方法为

    define N 1000+5
    int a[N][N]
    a[i][j]=1//其从i到j有边,其权值为1。一般当图是没有权重的
    		  //就视为其权重为1
    

    前向星

    前向星和邻接矩阵的不同是,它使用主要存储边的方式来存储整个图的信息。其是用一个数据结构来定义而成

    int head[maxn]//存储每一个边的起始位置
    struct node{
    	int from;
    	int to;
    	int val;
    }
    node edge[maxn];
    

    前向星是按照边的起点来进行排序,当边的起点相同时就按照边的终点来排序,当边的起点和终点都相同时,就按照此边的权值来排序,其比较代码如下:

    bool cmp(node a,node b){
    	if(a.from==b.fron&&a.to==b.to) return a.val<b.val;
    	if(a.from==b.from) return a.to<b.to;
    	return a.from<b.from;
    }
    

    其读入数据的代码如下:

    int n,m;
    cin>>n>>m;
    for(int i=0;i<m;i++) {cin>>edge[i].from>>edge[i].to>>edge[i].val;}
    sort(edge,edge+m,cmp);
    memset(head,-1,sizeof(head));
    head[edge[0].from]=0;
    for(int i=1;i<m;i++){
    if(edge[i].from!=edge[i-1].from) head[edge[i].from]=i;
    

    遍历代码:

    for(int i=1;i<=n;i++){
    	for(int k=head[i];edge[k].from==i&&k<m;k++){
    		cout<<edge[k].from<<' '<<edge[i].to<<' '<<edge[i].val;
    	}
    }	
    

    其时间复杂度多取决于排序算法,所以为O(mlogm)其空间复杂度为O(m+n)。前向星有很优点,但是其不可以直接判断某两点之间是否有边。

    邻接表

    邻接表就是视为每一个边为一个队列,如果有和这个边相连的顶点,则直接帮这个顶点入队到这个边对应的队列里。其的数据单元也是用自定义的数据结构存储的。

    struct edgenode{
    	int to;
    	int val;
    	edgenode * next;
    }
    struct vexnode{
    	int from;
    	edgenode * front;
    }
    vexnode vex[maxn];
    

    其存储信息:

    cin>>i>>j>>w;
    edgenode * p=new edgenode;
    p->to=j;
    p->val=w;
    p->next=vex[i].front;
    vex[i].front=p;
    

    遍历代码:

    for(int i=1;i<=n;i++){
    	for(int edgenode * k=vex[i].front;k!=NULL;k=k->next){
    		cout<<i<<' '<<k->to<<' '<<k->val<<endl;
    	}
    }
    

    当然,我们可以用STL库里的vector模拟链表来实现
    链表的创建:

    vector<vector<pair<int,int>>>g;
    //这里创建了一个vector套vector的数组,这个数组在使用
    //的时候需要定义下:g=vector<vector<pair<int,int>>>(n);放可是直接使用
    

    其存储信息:

    int i,j,w;
    cin>>i>>j>>w;
    g[i].push_back(make_pair(j,w));
    g[j],push_back(make_pair(i,w));
    

    其遍历代码:

    for(int i=1;i<=n;i++){
    	for(pair<int,int> to:g[x]){
    		cout<<x<<' '<<to.frist<<' '<<to.second<<endl;
    	}
    }
    

    链式前向星

    链式前向星又叫静态链表,是提高其构造效率来创造出来的一种高效的数据结构。

    int head[maxn];
    struct edgenode{
    	int to;
    	int w;
    	int next;
    }
    edgenode edge[maxn];
    

    信息存储:

    int i,j,w;
    cin>>i>>j>>w;
    edge[k].to=j;//这里的k代表的是这是你存储的第k条边
    edge[k].w=w;
    edge[k].next=head[i];
    head[i]=k;
    

    遍历代码:

    for(int i=1;i<=n;i++){
    	for(k=head[i];k!=-1;k=edge[k].next){
    		cout<<i<<' '<<edge[k].to<<' '<<edge[k].w<<endl;
    	}
    }
    
    展开全文
  • 常见存储数据结构

    千次阅读 2018-06-18 23:48:55
    常见存储数据结构 最近在看存储和数据库方面书籍,遇到了多种数据结构,做个简单总结,有任何理解问题也请大佬明示。╮( ̄▽ ̄)╭ B+树 B+tree常用于多种数据库存储引擎中,它是B tree(一种自平衡树状...

    常见存储数据结构

    最近在看存储和数据库方面的书籍,遇到了多种数据结构,做个简单总结,有任何理解问题也请大佬明示。╮( ̄▽ ̄)╭


    B+树

    这里写图片描述
    B+tree常用于多种数据库存储引擎中,它是B tree(一种自平衡的树状数据结构)的变种,区别在于非叶子节点不存储实际数据信息。mysql Innodb的聚集索引也使用了这种数据结构,以支持随机读写、范围扫描、排序等特性,同时由于其高度相对低(一般为2-3)可以有效减少io次数,提高读取效率。相对于hash存储引擎,它能支持like (str%)的索引扫描。
    1.B+树中,所有非叶子节点的内部节点数量相等。
    2.B+树种,非叶子节点不存储实际的数据信息,只存放节点信息。在innodb的聚集索性中,通过这种数据结构能减大大提高非叶子节点的节点存贮的信息量。Innodb按page存放树的每个节点,page默认为16kb,若每个非叶子节点的内部节点长度为20字节,带数据的叶子节点每个内部节点长度为100字节。则一个高度为3的B+树可以存放(16*1024/20)^2(*16*1024/100),约1亿条数据。
    3.B+树种,查找最大值和最小值十分方便,时间复杂度为o(1),对于随机查找其效率也十分稳定,并且最多读取h-1次磁盘页。
    4.在B+树中,叶子节点的每一个节点都有指向下一个叶子节点的指针,从而使遍历获取排序更加方便快捷。


    LSM树

    这里写图片描述
    LSM tree(Log-structured merge-tree)。就是将对数据的写操作增量保存在内存中,达到指定大小后将这些操作批量写入磁盘,读取的时候需要合并磁盘中的历史数据和内存中的最近写操作。LSM树规避了磁盘随机写的问题,但是读取时候需要访问多个数据文件。
    1.通常LSM在写入时会记录日志到磁盘中然后写入内存,防止数据丢失。
    2.在从内存同步到磁盘的过程中,会先对数据进行分组排序,然后写入文件系统中。
    3.数据文件会在一定条件下触发合并操作,按主键迭代出所有记录,抛弃掉没有价值的,否则生成到新的数据文件中。
    4.通常数据文件的索引信息会常驻内存,加速查找,减少磁盘io。


    HASH

    这里写图片描述
    HASH作为一种常见的数据结构,其对应的存储系统被称之为键值(Key-Value)存储系统。应用该数据结构的应用包括redis、memcache、Bitcask、Amazon Dynamo等。使用该数据结构可以极快的检索到所需的数据,使用这种数据结构能带来良好的性能提升。
    1.通常这类存贮系统只支持=、!=、IN等查询操作,对范围查找,排序则无法支持。
    2.该类引擎通常会在hash表里面存贮具体的数据信息、者对应数据信息所在数据文件的序号、位置、长度等信息。
    3.对于写操作,如果全部数据存贮在内存hash表中,则直接更新内存。如果存贮在磁盘中,则追加一条记录,并更新内存hash表的指向信息。
    4.对于冗余数据,通常需要做数据文件合并、垃圾回收等操作。


    TSM树

    TSM(Time Structured Merge Tree),TSM tree是Influxdb基于LSM tree结构的一中变种。influxdb是目前十分流行的时序数据库,性能良好。由于influxdb中存在的数据保存策略,并且每行数据都有时间戳,TSM tree 针对这些特性做了优化。
    1.Shard是influx中重要的特征,TSM文件系统中,每个shard都有自己独立的cache、wal、tsm文件,当需要释放过期数据时,直接释放掉文件系统中对应的shard会比LSM中的删除操作更加高效快捷。
    2.TSM中通过元数据、TSM文件索引做两级索性,优化了查询效率。


    参考资料

    [1]维基百科,LSM tree
    [2]维基百科,B+Tree
    [3]TMS存储引擎
    [4]《大规模分布式存储系统:原理解析与架构实战》杨传辉
    [5]《高性能mysql(第3版)》施瓦茨 (Baron Schwartz) / 扎伊采夫 (Peter Zaitsev) / 特卡琴科 (Vadim Tkachenko)

    展开全文
  • 的常见存储结构及各自优缺点

    千次阅读 2020-02-24 16:28:45
    本文将介绍图的常见存储结构及各自优缺点 邻接矩阵 邻接表 十字链表 邻接多重表 边集数组 eg: 无向图: 有向图: 邻接矩阵 用两个数组来表示图:一个一维数组存储图中顶点信息,一个二维数组(称为邻接矩阵)...

    以下说法均建立在简单图上,即无环无重复边的图。

    本文将介绍图的常见存储结构及各自的优缺点

    1. 邻接矩阵
    2. 邻接表
    3. 十字链表
    4. 邻接多重表
    5. 边集数组

    邻接矩阵

    用两个数组来表示图:一个一维数组存储图中顶点信息,一个二维数组(称为邻接矩阵)存储图中边(无向图)或弧(有向图)的信息

    若图有n个顶点,则邻接矩阵则为一个n*n的方阵
    定义为:
    在这里插入图片描述
    eg:
    在这里插入图片描述

    根据定义,可知对角线的值无论是无向图还是有向图均为0。
    对于无向图,邻接矩阵是对称的,但有向图并无该特性。

    优点:

    容易获得每个顶点的度,特别是对于有向图,获得顶点i的出度,只需遍历第i行,即arc[i]的值,入度也只需遍历第i列,即arc[][i]。

    缺点:

    对于边数相对顶点较少的图,浪费了极大的存储空间

    邻接表

    如上所述,顺序存储可能造成存储空间浪费的问题,所以就引出了链式存储结构

    • 对于顶点数组,每个数据元素需要存储指向第一个邻接点的指针
    • 每个顶点Vi的所有邻接点构成一个线性表,并用单链表存储;无向图称为顶点Vi的边表,有向图称为顶点Vi为弧尾的出边表
      在这里插入图片描述
      如图
    • 顶点表的各个结点由data跟firstedge两个域表示。
      data是数据域,存储顶点的信息,firstedge是指针域,指向此顶点的第一个邻接点。
    • 边表结点由adjvex和next两个域组成。
      adjvex是邻接点域,存储某顶点的邻接点在顶点中的下标,next则存储指向边表中下一个结点的指针。

    但正如定义,对于有向图,邻接表只存储了各顶点相应的出边,若要便利地获得入度,则可以同理建立一个逆邻接表:对每个顶点都建立一个链接为Vi为弧头的表
    在这里插入图片描述
    缺点:
    对于有向图,出度入度是不兼得的,要两样都获得就只能分别建立、遍历对应的邻接表和逆邻接表。空间利用率和效率也不高。

    十字链表

    把邻接表和逆邻接表结合起来,就得到了十字链表。所以十字链表也是专门为有向图设计的

    • 重新定义顶点表结点结构为:
      在这里插入图片描述啊啊
      firstin、firstout 分别指向入边表、出边表中的第一个结点

    • 重新定义边表结点结构为:
      在这里插入图片描述
      注意 tail、head分别指弧尾、弧头,不要混乱。
      tailvex、headvex分别指弧起点(即弧尾)、弧终点(即弧头)在顶点表中的下标。
      headlink是指入边表指针域,指向终点相同的下一条边(即弧头相同,所以命名为headlink);
      taillink是指出边表指针域,指向起点相同的下一条边(即弧尾相同,所以命名为taillink)

    在这里插入图片描述
    当然了,并不是说十字链表一定比邻接表好,也是看实际需求是否需要同时访问出入度。

    邻接多重表

    既然十字链表是有向图的优化存储结构,那邻接表对于无向图有没有什么缺点呢?答案是肯定的。

    若我们关注的重点是顶点,那邻接表自然是不错的选择;
    但如果更关注边的操作,比如删除边(V0,V2)
    在这里插入图片描述
    我们就需要删除图中的两个阴影结点,显然是比较麻烦的。

    所以邻接多重表就应运而生了。

    • 重新定义边表结点结构为:
      在这里插入图片描述
      其中ivex、jvex是与某条边依附的两个顶点在顶点表中的下标,
      ilink指向依附顶点 ivex的下一条边,同理,
      jlink指向依附顶点 jvex的下一条边。

    当然,因为是无向图,所以ivex跟jvex是什么顺序都是无所谓的,但为了绘图方便,此处将ivex值设置得与一旁顶点下标相同。
    在这里插入图片描述
    邻接多重表和邻接表的差别,仅仅在于同一条边在邻接表中用两个结点表示,而在邻接多重表中只有一个结点。
    所以上述的删除(V0,V2)边,只需要把图中浅蓝色的边对应的链接指向改成^即可。

    边集数组

    邻接表关注的是顶点,十字链表则是对有向图的优化,但关注的重点仍然是顶点;邻接多重表则是对无向图的优化,关注重点是边。

    那缺了什么了?没错,就是有向图的关注边的操作时所用的结构,就是本节所说的边集数组。

    边集数组由两个一维数组构成。
    一个存储顶点的信息(即顶点数组),
    另一个是存储边的信息:边数组的每个数据元素由一条边的起点下表(begin)、终点下标(end)组成。
    在这里插入图片描述
    人如其名,边集数组关注的是边的集合。在边集数组中查找一个顶点的度需要扫描整个边数组,效率并不高。因此更适合与边相关的操作,而不适合对顶点相关的操作。

    在这里插入图片描述

    汇总

    结构 优点 缺点 关注点
    邻接矩阵 通用性强 需求空间大
    邻接表 节省空间 对有向图无法兼备出度入度 顶点
    十字链表 对有向图兼得出度入度 有向图、顶点
    邻接多重表 无向图边操作简单 无向图、边
    边集数组 有向图边操作简单 有向图、边

    缺点为空并不代表没有缺点,关注点一列的对应的其实就是优点,反之则是缺点。

    参考内容:《大话数据结构》
    若有误欢迎指出。

    展开全文
  • 数据的存储结构

    2017-10-07 14:48:34
     存储结构是数据的逻辑结构用计算机语言的实现,常见的存储结构有: 顺序存储 , 链式存储 , 索引存储 ,以及 散列存储 。其中散列所形成的存储结构叫 散列表(又叫哈希表) ,因此哈希表也是一种存储结
  • 1.线性表的的动态分配顺序存储结构#define LIST_INIT_SIZE 100 //线性表存储空间初始分配量 #define LISTINCREMENT 100 //线性表存储空间分配增量 typedef struct { ElemType *elem; //存储空间基址 int ...
  • 数据4种逻辑结构: 1.集合结构:数据元素之间没有任何关系....常见的4种数据存储结构: 1.顺序存储结构:借助数据元素之间的相对位置来表示元素之间的逻辑结构.(vector动态数组、deque双端队列、stack栈容器、queue队...
  • C++中几种常见的顺序存储结构

    千次阅读 2018-04-13 10:19:48
    C++中容器类包括“顺序存储结构”和“关联存储结构”,前者包括vector,list,deque等;后者包括set,map,multiset,multimap等。若需要存储元素数在编译器间就可以确定,可以使用数组来存储,否则,就需要用到...
  • 常见结构存储系统架构

    千次阅读 2019-03-01 22:39:24
    结构化数据一般指存储在数据库中,具有一定逻辑结构和物理结构的数据,最为常见的存储在关系数据库中的数据;非结构化数据:一般指结构化数据以外的数据,这些数据不存储在数据库中,而是以各种类型的文本形式存放...
  • 树的常见的三种链表存储结构

    千次阅读 2018-09-08 11:16:11
    // - - - - - 树双亲表存储表示 - - - - - #define MAX_TREE_SIZE 100 typedef struct PTNode { //结点结构 ElemType data; int parent; //双亲位置域 }PTNode; typedef struct { //树结构 PTNode nodes[MAX_TR...
  • 继续接去年的常见数据结构和算法总结 系列随笔记录 一、计算机里进行非数值处理对象基本上是字符串数据,比处理浮点和整数都要复杂 string串定义:由 0 个或多个 字符 组成 有限 序列,通常记为:s =“a1 a2...
  • 数据结构之存储结构

    2017-04-12 21:15:24
    存储结构是数据的逻辑结构用计算机语言的实现,常见的存储结构有: 顺序存储 , 链式存储 , 索引存储 ,以及 散列存储 。其中散列所形成的存储结构叫 散列表(又叫哈希表) ,因此哈希表也是一种存储结构...
  • ​ Python中常见的数据结构可以统称为容器。序列(如列表和元组)、映射(如字典)以及集合(set)是三类主要的容器。线性数据结构分类:栈(stack)--先进后出、 队列(queue)-先进先出、双端队列(deque)、链表(LinkedList)...
  • 常见的数据结构 1.栈 栈,tack,又称堆栈,他是运算受限的线性表。其限制是只允许在一端进行插入和删除操作。 存取特点:先进后出。 压栈:将指定元素存储到栈顶。 弹栈:取出栈顶的元素。 2.队列 队列,...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 10,767
精华内容 4,306
关键字:

常见的存储结构