(C/C++)数据结构三:串、广义表

串:

 

//串的顺序存储结构
#define MAXLEN 255
typedef struct{
    char ch[MAXLEN+1];//存储串的一维数组
    int length;//串的当前长度
}SString;
//串的链式存储结构-块链结构
#define CHUNKSIZE 80//块的大小
typedef struct Chunk{
    char ch[CHUNKSIZE];
    struct Chunk *next;
}Chunk;

typedef struct{
    Chunk *head,*tail;//串的头指针和尾指针
    int curlen;//串的当前长度
}LString;//字符串的块链结构

//串的模式匹配算法
/*确定主串中所含子串第一次出现的位置*/
/*BF算法:穷举*/ 
/*KMP算法*/


/*BF算法*/
/*Index(S,T,pos)*/
/*将主串的第pos个字符和模式串的第一个字符比较,
  若相等,继续逐个比较后续字符;
  若不等,从主串的下一字符起,重新与模式串的第一个字符比较*/

/*直到主串的一个连续子串序列与模式串相等,返回值为S中与T匹配的
  子序列第一个字符的序号,即匹配成功。否则,匹配失败,返回值0*/

int Index BF(SString S,SString T){
    int i = 1, j = 1;
    while(i<=S.length && j<=T.length){
         if(s.ch[i] == t.ch[j]){
            ++i;
            ++j;//主串和子串依次匹配下一个字符
         }
         else{
            i = i-j+2;
            j = 1;//主串、子串指针回溯重新开始下一次匹配
         }
    }   
    if(j>T.length)return i-T.length;//返回匹配的第一个字符的下标
    else return 0;//模式匹配不成功   
}

/*KMP算法*/
/*Index(S,T,pos)*/

int Index KMP(SString S,SString T,int pos)
{
    int i = pos,j = 1;
    while(i<S.length&&j<T.length)
    {
        if(j==0||S.ch[i] == T.ch[j]){
            i++;j++;
        }
        else j = next[j];//i不变,j后退
    }
    if(j>T.length)return i-T.length;//匹配成功
    else return 0;//返回不匹配
}
void get_next(SString T,int &next[])
{
    int i = 1,next[1] = 0,j = 0;
    while(i<T.length)
    {
        if(j==0||T.ch[i] == T.ch[j])
        {
            ++i;++j;
            next[i] = j;
        }
        else j = next[j];
    }
}
/*kmp推荐看https://www.bilibili.com/video/BV16X4y137qw*/

数组:

各位元素个数为m1,m2...,mn,下标为i1,i2,...,in的数组元素的存储位置:

LOC = a + \sum_{j=1}^{n-1}i_{j} * \coprod_{k=j+1}^{n}m_{k} +i_{n}

特殊矩阵的压缩存储:

若多个数据元素的值都相同,则只分配一个元素值的存储空间,且零元素不占存储空间。

1、对称矩阵:只存储下(上)三角(包括主对角线)的数据元素,共占用n(n+1)/2个元素空间

可以以行序为主序将元素存放到一个一维数组sa[n(n+1)/2]中。

2、三角矩阵:对角线以下(以上)的数据元素(不包括对角线全部为常数c)重复元素c共享一个元素存储空间,共占用n(n+1)/2+1个元素空间

3、对角矩阵(带状矩阵):以对角线的顺序存储

4、稀疏矩阵(0的占比大于95%):

        (1)运用三元组顺序表,在C语言中用结构体来表示三元组顺序表,表示行标,列标,数据值。

        (2)运用十字链表,矩阵的每一个非零元素用一个结点表示,该结点出了行、列、值还有两个域:right链接同一行中的下一个非零元素,down链接同一列的下一个非零元素

广义表:

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


广义表的性质:

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

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

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

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

(5)广义表可以是一个递归的表,深度是无穷值,长度是有限值,如F = (a,F)

(6)广义表是多层次结构,广义表的元素可以是单元素,也可以是子表,而子表的元素还可以是子表

广义表和线性表的区别:

广义表可以看成是线性表的推广,线性表是广义表的特例,它可以兼容线性表、数组、树、图

广义表的基本运算:

求表头GetHead,求表尾GetTail

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值