数据结构--串、数组、广义表

串(String):零个或多个任意字符组成的有限序列

  • 空串用∅表示

子串:一个串中任意个连续字符组成的子序列(含空串)称为该串的子串
真子串是指不包含自身的所有子串
几个术语

  • 子串:串中任意个连续字符组成的子序列称为该串的子串
  • 主串:包含子串的串相应的称为主串
  • 字符位置:字符在序列中的序号为该字符在串中的位置
  • 子串位置子串第一个字符在主串中的位置
  • 空格串:由一个或多个空格组成的串,与空串不同

串相等:当且仅当两个串的长度相等并且各个对应位置上的字符都相同时,这两个串才是相等的。
串的顺序存储结构

#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算法(Brute-Force,又称古典的、经典的、朴素的、穷举的 )
  • KMP算法(特点:速度快)

BF算法,亦称简单匹配算法,采用穷举的思路

  • 算法的思路是从主串的每一个字符开始依次与子串的字符进行匹配 匹配失败要回溯 i=i-j+2 j=1(从头开始)

Index(S,T,pos)

  • 将主串的第pos个字符和模式串的第一个字符比较
  • 若相等,继续逐个比较后续字符
  • 若不等,从主串的下一个字符起,重新与模式串的第一个字符比较
  • 直到主串的一个连续字符序列和模式串相等。返回值为S(主串)中与T(模式串)匹配的子序列的第一个字符的序号,即匹配成功。否则匹配失败,返回0
int Index_BF(SString S,SString T,int pos)
{
    int i=pos;
    int j=1;
    while(i<S.length&&j<=T.length)
    {
        if(S.ch[i]==T.ch[i])//主串和子串依次匹配下一个字符
        {
            ++i;
            ++j;
        }
        else//主串,子串指针回溯重新开始下一次匹配
        {
            i=i-j+2;
            j=1;
        }
        if(j>=T.length)
            return i-T.length;//返回匹配的第一个字符的下标
        else 
            return 0;//模式匹配不成功
    }
}
  • 若主串长度n,子串长度m,算法复杂度O(m*n)

KMP算法

  • 定义next[j]函数,表明当模式中第j个字符与主串中相应字符“失配”时,在模式中需重新与主串中该字符进行比较的字符的位置

next[j]=

  1. max{k|1<k<j,且从头开始的k-1个元素=j前面的k-1个元素} 当此集合非空时
  2. 0 当j=1时
  3. 1 其它情况
int Index_BF(SString S,SString T,int pos)
{
    int i=pos;
    int j=1;
    while(i<S.length&&j<=T.length)
    {
        if(j==0||S.ch[i]==T.ch[i])//主串和子串依次匹配下一个字符
        {
            ++i;
            ++j;
        }
        else
        {
           j=next[j];//i不变,j后退
        }
        if(j>T.length)
            return i-T.length;//返回成功返回匹配的第一个字符的下标
        else 
            return 0;//模式匹配不成功
    }
}
  • next[j]可以改进成nextval[j],不多介绍了

数组

  • 数组:按一定格式排列起来的,具有相同类型的数据元素的集合
  • 一维数组:若线性表中的数据元素为非结构的简单元素,则称为一维数组
  • 一维数组的逻辑结构:线性结构。定长的线性表
  • 声明格式:数据类型 变量名称[长度]
  • 二维数组:若一维数组中的数据元素又是一维数组结构,则称为二维数组
  • 二维数组的逻辑结构
    非线性结构:每一个数据元素既在一个行表中,又在一个列表中
    线性结构:该线性表的每个数据 元素也是一个定长的线性表
  • 在C语言中,一个二维数组类型也可以定义为一维数组类型(其分量类型为一维数组类型)即:typedef elemtype array2[m][n]; 等价于 typedef elemtype array1[n]; typedef array1 array2[m];
  • 三维数组:若二维数组中的元素又是一个一维数组,则称作三维数组
  • n维数组:若n-1维数组中的元素又是一个一维数组结构,则称作n维数组
  • 结论:线性表结构是数组结构的一个特例,而数组结构又是线性表结构的扩展
  • 数组特点:结构固定–定义后,维数和维界不再改变
  • 数组的基本操作:除了结构的初始化和销毁之外,只有取元素和修改元素值的操作
  • 数组一般都是采用顺序存储结构来表示
  • 注意:数组可以是多维的,但存储数据元素的内存单元地址是一维的,因此,在存储数组结构之前,需要解决将多维关系映射到一维关系的问题
  • 一维数组:LOC(i)=
    1)LOC(0)=a, i=0;
    2)LOC(i-1)+L=a+i*L,i>1
  • 二维数组:以行序为主序
    设数组开始存储位置LOC(0,0),存储每个元素都需要L个存储单元数组元素a[i][j]的存储位置是:LOC(i,j)=LOC(0,0)+(n*i+j)*L

特殊矩阵的压缩存储

  • 矩阵:一个由m×n个元素排成的m行n列的表
  • 矩阵的常规存储:
    将矩阵表述为一个二维数组
  • 矩阵的常规存储的特点:
    可以对其元素进行随机存取
    矩阵运算非常简单;存储的密度是1
  • 不适宜常规存储的矩阵
    值相同的元元素很多且呈某种规律分布;零元很多
  • 矩阵的压缩存储:
    为多个相同的非零元素只分配一个存储空间;对零元素不分配空间
  • 特殊矩阵的压缩存储
    1、什么是压缩存储?
    若多个数据元素的值都相同,则只分配一个元素值的存储空间,且零元素不占存储空间
    2、什么样的矩阵能够压缩?
    一些特殊矩阵,如:对称矩阵,对角矩阵,三角矩阵,稀疏矩阵等
    3、什么叫稀疏矩阵?
    矩阵中非零元的个数较少(一般小于5%)

广义表

广义表(又称列表)是n>=0个元素的有限序列,其中每一个ai或者是原子,或者是一个广义表

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

广义表的性质

  • 广义表中的数据元素有相对次序;一个直接前驱和一个直接后继
  • 广义表的长度定义为最外层所包含元素的个数
  • 广义表的深度定义为该广义表展开后所包含括号的重数
    注意:原子的深度为0,空表的深度为1
  • 广义表可以为其它广义表共享
  • 广义表可以是一个递归的表
    注意:递归表的深度是无穷值,长度是有限值
  • 广义表是多层次结构,广义表的元素可以是单元素,也可以是子表,而子表的元素还可以是子表,。。。

广义表和线性表的区别

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

广义表的基本运算

  1. 求表头(GetHead(L)):非空广义表的第一个元素,可以是一个原子也可以是一个子表
  2. 求表尾(GetTail(L)):非空广义表除去表头元素以外其它元素构成的表。表尾一定是一个表
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

&*Savior

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值