首页 > 其他分享 >数据结构——广义表

数据结构——广义表

时间:2024-09-25 20:22:29浏览次数:10  
标签:元素 表头 原子 tag 广义 子表 数据结构

广义表的概念

        广义表(又称列表Lists)是n>=0个元素a0,a1,...,an-1的有限序列,其中每一个ai可以是原子,或者是一个广义表。

广义表和线性表的区别:线性表的元素是单一的类型,而广义表的元素可以是不同类型,其元素也可以是一个广义表(子表)。

  • 广义表通常记作:LS=(a1,a2,...,an)        其中: LS为表名,n为表的长度,每一个 ai为表的元素。
  • 习惯上,一般用大写字母表示广义表,小写字母表示原子。
  • 表头:若LS非空(n>=1)则其第一个元素a1就是表头。 记作head(LS)= a1 注:表头可以是原子,也可以是子表。
  • 表尾:除表头之外的其他元素组成的表。记作tail(LS)= (a2,...,an)。注:表尾不是最后一个元素,而是一个子表。

 广义表的性质

(1)广义表中的数据元素有相对次序;一个直接前驱和一个直接后继。

(2)广义表的长度定义为最外层所包含元素的个数;

如:C = (a,(b,c))是长度为2的广义表。

(3)广义表的深度定义为该广义表展开后所包含括号的重数;

注意:“原子”的深度为0,“空表”的深度为1。

 (4)广义表可以为其他广义表共享;如:广义表B就共享表A,在B中不必列出A的值,而是通过表名来引用,B = (A)。

(5)广义表可以是一个递归的表,如:F = (a1,F)这种把自身当作元素的广义表

注意:递归表的深度是无穷值,长度是有限值。

(6)广义表是多层次结构,广义表的元素可以是单元素,也可以是子表,而子表还可以是子表,...。可以用图形象地表示。

广义表和线性表的区别

  • 广义表可以看成是线性表的推广,线性表是广义表的特例。
  • 广义表的结构相当灵活,在某种前提下,它可以兼容线性表、数组、树和有向图等各种常用的数据结构。
  • 当二维数组的每行(或每列)作为子表处理时,二维数组即为一个广义表。
  • 另外,树和有向图也可以用广义表来表示。
  • 由于广义表不仅集中了线性表、数组、树和有向图等常见数据结构的特点,而且可有效地利用存储空间,因此在计算机的许多应用领域都有成功使用广义表的实例。

广义表的基本运算

(1)求表头GetHead(L):非空广义表的第一个元素,可以是一个原子,也可以是一个子表

(2)求表尾GetTail(L):非空广义表的除去表头元素以外其它元素所构成的表。表尾一定是一个表

 广义表的存储结构

1)存储结构一

  • 存储结构一如下示意图所示:表示原子的节点由两部分构成,分别是 tag 标记位和原子的值,表示子表的节点由三部分构成,分别是 tag 标记位、hp 指针和 tp 指针。

(1)tag 标记位用于区分此节点是原子还是子表,通常原子的 tag 值为 0,子表的 tag 值为 1;
(2)子表节点中的 hp 指针用于连接本子表中存储的原子或子表;
(3)tp 指针用于连接广义表中下一个原子或子表。

 

  • 广义表中两种节点的表示代码定义如下:
    定义中使用了 union 共用体,因为同一时间此节点不是原子节点就是子表节点,当表示原子节点时,就使用 atom 变量;反之则使用 ptr 结构体。
typedef struct GNode{
    int tag;         // 标志域, 0表示原子, 1表示子表
    union{
        char atom;   //  原子结点的值域
        struct{
            struct GNode * hp, *tp;
        }ptr;   // 子表结点的指针域, hp指向表头, tp指向表尾
    }subNode;
}GLNode, *Glist;

 2)存储结构二

  • 另一种存储结构的原子的节点也由三部分构成,分别是 : tag 标记位、原子值和 tp 指针构成;表示子表的节点由三部分构成,分别是 : tag 标记位、hp 指针和 tp 指针,示意图如下:

代码定义如下: 

typedef struct GNode {
    int tag;                // 标志域, 0表示原子, 1表示子表
    union {
        int atom;          // 原子结点的值域
        struct GNode* hp;  // 子表结点的指针域, hp指向表头
    }subNode;
    struct GNode* tp;     // 这里的tp相当于链表的next指针, 用于指向下一个数据元素
}GLNode, *Glist;

广义表的复制

  • 广义表的复制思想 : 任意一个非空广义表来说,都是由两部分组成:表头和表尾。反之,只要确定的一个广义表的表头和表尾,那么这个广义表就可以唯一确定下来。因此复制一个广义表,也是不断的复制表头和表尾的过程。如果表头或者表尾同样是一个广义表,依旧复制其表头和表尾。
  • 复制广义表的过程,其实就是不断的递归复制广义表中表头和表尾的过程,递归的出口有两个:
  • 如果当前遍历的数据元素为空表,则直接返回空表。
  • 如果当前遍历的数据元素为该表的一个原子,那么直接复制,返回即可

实现代码:

// 广义表的复制, C为复制目标广义表,*T为指向复制后的广义表
void copyGlist(Glist C, Glist *T){
    // 如果C为空表,那么复制表直接为空表 
    if (!C) {
        *T=NULL;
    }
    else{
        *T=(Glist)malloc(sizeof(GNode)); // C不是空表,给T申请内存空间
        // 申请失败,程序停止
        if (!*T) {
            exit(0);
        }
        (*T)->tag=C->tag; // 复制表C的tag值
        // 判断当前表元素是否为原子,如果是,直接复制
        if (C->tag==0) {
            (*T)->atom=C->atom;
        }else{  //运行到这,说明复制的是子表
            copyGlist(C->ptr.hp, &((*T)->ptr.hp));  //复制表头
            copyGlist(C->ptr.tp, &((*T)->ptr.tp));  //复制表尾
        }
    }
}

标签:元素,表头,原子,tag,广义,子表,数据结构
From: https://blog.csdn.net/weixin_74209413/article/details/142523747

相关文章

  • 数据结构(Day20)
    一、学习内容树形结构概念(1树是n个元素的有限集合n==0空树n>0有且只有一个根结点其他的结点互不相交的子集树具有递归性:树中有树树的术语(结点:树的数据元素(根结点:唯一的没有前驱(没有双亲)叶子:终端结点不是唯一的没有后继(没有孩子)度为0分......
  • 架构师日记-从数据库发展历程到数据结构设计探析
    一数据库发展史起初,数据的管理方式是文件系统,数据存储在文件中,数据管理和维护都由程序员完成。后来发展出树形结构和网状结构的数据库,但都存在着难以扩展和维护的问题。直到七十年代,关系数据库理论的提出,以表格形式组织数据,数据之间存在关联关系,具有了良好的结构化和规范化特......
  • Set 数据结构
    Set是一种集合数据结构,它类似于数组,但与数组不同的是它没有重复值一、创建Set创建一个新的集合,通过add方法添加数据constmySet=newSet()mySet.add(1)mySet.add(2)mySet.add(2)mySet.add(3)mySet.add(4)console.log(mySet)直接初始化集合constmySet=newS......
  • 【数据结构】图的遍历
    快乐的流畅:个人主页个人专栏:《C游记》《进击的C++》《Linux迷航》远方有一堆篝火,在为久候之人燃烧!文章目录引言一、深度优先遍历1.1定义1.2实现二、广度优先遍历2.1定义2.2实现三、DFS与BFS的对比引言前置知识:【数据结构】图的概念和存储结......
  • 架构师日记-从数据库发展历程到数据结构设计探析
    一数据库发展史起初,数据的管理方式是文件系统,数据存储在文件中,数据管理和维护都由程序员完成。后来发展出树形结构和网状结构的数据库,但都存在着难以扩展和维护的问题。直到七十年代,关系数据库理论的提出,以表格形式组织数据,数据之间存在关联关系,具有了良好的结构化和规范......
  • 数据结构:二叉树 (Heap堆篇) 手把手带你入门数据结构~ (简单易懂超详细~)
    文章目录前言一、树的概念1.树的概念与结构2.树的特性3.树的相关术语4.树的表示方法5.树形结构实际场景二、二叉树1.二叉树的概念2.二叉树的结构3.满二叉树3.完全二叉树1.完全二叉树的概念2.完全二叉树的性质3.完全二叉树的结构三、堆1.堆的概念2.堆的......
  • 数据结构:双向链表(Doubly Linked List篇)手把手带你入门数据结构~
    文章目录前言一、双向链表的概念1.结构特点:2.优点:二、双向链表的实现1.双向链表的结构2.双向链表初始化3.双向链表销毁4.双向链表打印5.双向链表尾插6.双向链表头插7.双向链表尾删8.双向链表头删9.双向链表查找10.双向链表指定位置插入11.双向链表指定位置......
  • 16年408-数据结构
    第一题:解析:经过查表可知:a的链接地址是1010H,而1010H正是表中e所在的位置。由题可知f存放的位置是1014H,要将f链接在a和e的中间,则a后面要链接f,f后面要链接e,e的链接地址不变因此答案是1014H,1004H,1010H,答案选D第二题:解析:选D。p->next->prev:p的后一个节点的prev指针......
  • 15年408-数据结构
    第一题解析:栈第一次应该存main的信息。然后进入到main里面,要输出S(1),将S(1)存入栈内,进入到S(1)中,1>0,所以还要调用S(0)S(0)进入栈中,此时栈内从下至上依次是main(),S(1),S(0)答案选A第二题:解析:先序序列个数为0时,二叉树个数是1:先序序列个数为1时,二叉树个数是1:......
  • 数据结构算法题
    目录轮转数组原地移除数组中所有元素val删除有序数组中的重复项合并两个有序数组轮转数组思路1:1.利用循环将最后一位数据放到临时变量(n)中2.利用第二层循环将数据往后移一位3.将变量(n)的数据放到数组第一位时间复杂度:O(N^2)空间复杂度:O(1)思路2:1.创建一个空间......