串,数组和广义表

本文介绍了数据结构中的串、数组和广义表的基本概念,包括串的定义、长度、空串和子串,数组的定义和特点,以及二维数组的概念。同时,阐述了串的常见操作如比较、复制和连接,数组的存取和修改操作。广义表作为一种更灵活的数据结构,允许元素为其他广义表,文章详细说明了广义表的存储结构和相关操作。
摘要由CSDN通过智能技术生成

串的定义:串是由零个或多个字符组成的有限序列,是数据元素为单个字符的特殊线性表。 

串长:串中所包含的字符个数。

空串:长度为零的串,它不包含任何字符。记作“∅”

空格串:由一个或多个空格组成的串,其长度为串中空格字符的个数。它与空串∅是不同的概念。

子串个数:2n+1

串与线性表的区别:

1.串的数据对象约束为字符集。

2.线性表的基本操作中,大多以“单个元素”作为操作对象;而串的基本操作中,通常以“串的整体”作为操作对象。

串与字符的区别:

 "a"串,长度为1的串。(除了要存储字符‘a',还要存储串长1)

 'a'字符a。(只存储字符‘a')
 

串的计算:

#include<string.h>
 
strcmp(char s1,char s2) //比较
strcpy(char to,char from) //复制
strcat(char to,char from) //连接
strlen(char s) //串长
Status Concat(SString &T,SString S1,SString S2)
{
    if(S1.length+S2.length<=MAXLEN)//不截断
    {
        for(i=1;i<=S1.length;i++) T.ch[i]=S1.ch[i];
        for(i=1;i<=S2.length;i++) T.ch[i+S1.length]=S2.ch[i];
        T.length=S1.length+S2.length;
        uncut = TRUE;
    }
    else //截断
    {
        for(i=1;i<=S1.length;it+) T.ch[i]=S1.ch[i];
        for(i=1;i<=MAXLEN-S1.length;i++) T.ch[i+S1.length]=S2.ch[i];
        T.length = MAXLEN;
        uncut = FALSE;
    }
    return uncut;
}

数组:

数组的定义:数组是由一组类型相同的数据元素构成的有序集合,每个数据元素称为一个数组元素(简称为元素),每个元素受n(n≥1)个线性关系的约束,每个元素在n个线性关系中的序号i1、i2、...、in称为该元素的下标,并称该数组为n维数组。

数组的特点:

1.元素本身可以具有某种结构,属于同一数据类型。

2.数组是一个具有固定格式和数量的数据集合。

二维数组是数据元素为线性表的线性表。

数组基本操作:

1.存取:给定一组下标,存储或读出对应的数组元素。

2.修改:给定一组下标,修改与其相对应的数组元素。

广义表:

 广义表是线性表的推广,也被称为列表(lists)。
广义表一般记作:
LS=(a1,a2,a3,…,a n)
  LS是表的名称,n是表的长度。在线性表的定义中,a i (1<=i<=n)只能限于单个元素,但是在广义表中a i 可以是 单个元素,也可以是广义表,分别称为广义表LS的原子和子表。 当广义表非空时,第一个元素(a1)被称为表头,其余元素(a2,a3,…,a n)被称为子表。

二,广义表的存储结构
  由于广义表的数据元素可以是原子和子表,因此很难用顺序存储结构来表示,通常采用链式存储结构,每个数据元素可以用一个结点来表示。
 由此我们需要2种数据结构来表示结点:一个是表结点,用来表示列表,另一个是原子结点,用来表示原子。

广义表的操作:


//返回一个空的广义表
Mul_Lists GetMulLists(void);
//构造广义表
void InitMulLists(Mul_Lists *LS, char *Num, LS_Data Data[], int Len);
//广义表是否为空
bool Empty(Mul_Lists *LS);
//销毁广义表
void Destroy(Mul_Lists *LS);
//获取广义表的长度
unsigned int Length(Mul_Lists *LS);
//获取广义表的深度
unsigned int Depth(Mul_Lists *LS);
//获取表头数据
LS_Data *GetHead(Mul_Lists *LS);
//获取表尾数据
LS_Data *GetTail(Mul_Lists *LS);
//插入元素(第一个元素)
void InsertFirst(Mul_Lists *LS, const LS_Data Data);
//删除元素(第一个元素)
LS_Data DeleteFirst(Mul_Lists *LS);
//遍历广义表
void Traverse(Mul_Lists* LS);

//构造广义表
void InitMulLists(Mul_Lists *LS, char *Num, LS_Data Data[], int Len)
{
    int len = 0;//记录表长度
    LS_Node *curPtr = NULL;
    //如果表的编号为空就直接返回
    if (!STRING_LEN(Num))
        return;
        //给头结点赋值,只做一次(即进入递归之后不能修改头结点)
    if (!LS->len)
    {
        LS->lastNode = LS->headPtr = GetListsNode(LIST);
        curPtr = LS->lastNode;
    }
    //进入递归后会执行else中的代码
    else
    {
        curPtr = GetListsNode(LIST);
        LS->lastNode->ptr.hp = curPtr;
        LS->lastNode = curPtr;
    }
    LS->len++;
    //表长加一
    ++len;
    //删除首字符
    DeleteString(Num);
    while (STRING_LEN(Num))
    {
        //修改LS中的表长
        LS->len = len;
        if (Num[0] == '(')
        {
            //记录尾结点
            LS->lastNode = curPtr;
            //进入递归
            InitMulLists(LS, Num, Data, Len);
        }
        else if (Num[0] == ',')
        {
            curPtr = LS->lastNode;
            curPtr->ptr.tp = GetListsNode(LIST);
            curPtr = curPtr->ptr.tp;
            LS->lastNode = curPtr;
            //表长加一
            ++len;
        }
        else if (Num[0] == ')')
        {
            break;
        }
        else
        {
            //链接新节点
            curPtr->ptr.hp = GetListsNode(ATOM);
            //给节点数据赋值
            curPtr->ptr.hp->value = Data[0];
            //移除第一个数据
            DeleteArray(Data, &Len);
        }
         //删除首字符
        DeleteString(Num);
    }
}


//销毁结点
static void FreeMulListsNode(LS_Node *Node)
{
    LS_Node *temp = NULL;
    while (Node)
    {
        if (Node->ptr.hp->Tag == ATOM)
        {
            //释放原子结点
            free(Node->ptr.hp);
        }
        else if (Node->ptr.hp->Tag == LIST)
        {
            //递归删除列表结点
            FreeMulListsNode(Node->ptr.hp);
        }
        //保存下一个结点的位置
        temp = Node->ptr.tp;
        //释放列表结点
        free(Node);
        Node = temp;
    }
}
//计算广义表深度
static int ListsDepth(LS_Node *Node)
{
    //如果表为空表时,直接返回长度1;
    if (PTR_IS_NULL(Node))
    {
        return 1;
    }
    //如果表为原子时,直接返回0;
    if (Node->Tag == ATOM)
    {
        return 0;
    }
    int max = 0; //设置表的初始长度为0;
    LS_Node *temp = Node;
    while (temp)
    {
        int dep = ListsDepth(temp->ptr.hp);
        if (dep > max)
        {
            max = dep; //每次找到表中遍历到深度最大的表,并用max记录
        }
        temp = temp->ptr.tp;
    }
    //程序运行至此处,表明广义表不是空表,由于原子返回的是0,而实际长度是1,所以,此处要+1;
    return max + 1;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值