串——零个和任意多个字符组成的有限序列称为串。
计算机上非数值处理的对象基本都是字符串
串相等:串长度相等,对应位置字符都相等。
类似于线性表的顺序存储结构,用一组地址连续的存储单元存储串值的字符序列。按照预定义的大小,为每个预定义的串变量分配一个固定长度的存储区。
#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 length; //串的当前长度
}LString;
但是链式存储有点是操作方便,缺点就是存储密度较低。为了克服这个缺点,可以将多个字符存放在一个结点中。
【算法思路】
①将主串的第pos个字符与模式串的第一个字符进行比较:
若相等,继续逐个比较后续字符;
若不等,从主串的下一个字符开始,重新与模式串的第一个字符进行比较。
②直到主串的一个连续字符串字符序列与模式串相等。返回值为S中与T匹配的子序列的第一个字符的序号,即匹配成功。否则,匹配失败。
【算法步骤】
① 分别利用计数指针i和j指示主串S和模式T中当前正待比较的字符位置,i初值为pos,j初值为1。
② 如果两个串均未比较到串尾,即i和j均分别小于等于S和T的长度时,则循环执行以下操作:
·S.ch[i]和T.ch[j]比较,若相等,则i和j分别指示串中下个位置,继续比较后续字符;
·若不等,指针后退重新开始匹配,从主串的下一个字符(i=i-j+2)起再重新和模式的第一个字符(j=1)比较。
③ 如果j>T.length,说明模式T中的每个字符依次和主串S中的一个连续的字符序列相等,则匹配成功,返回和模式T中第一个字符相等的字符在主串S中的序号(i-T.length);否则称匹配不成功,返回0。
【算法描述】
//返回模式T在主串S中第pos个字符开始第一次出现的位置。若不存在,则返回值为0
int Index_BF(SString S,SString T,int pos)
{
int i=pos,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; //匹配失败
}
【时间复杂度】
暴力匹配算法最坏的时间复杂度为O(n*m)
【优点和缺点】
优点:算法思路清晰明了
缺点:总是回溯到i-j+2的位置,模式串总是恢复到首字符位置j=1,因此算法时间复杂度高。
KMP算法较BF算法在算法效率上有了很大的提高。其改进在于:当一趟匹配过程中出现字符比较不等时,不需回溯i指针,而是利用已经得到的“部分匹配”的结果将模式向右“滑动”尽可能远的一段距离后,继续进行比较。
【时间复杂度】
O(m+n)
【定义】数组是由n个(n>=1)相同类型的数据元素构成的有限序列。
【二维数组】若一维数组中的数据元素又是一维数组结构,则称二维数组。
线性表结构是数组结构的一个特例,而数组结构又是线性表结构的拓展。
【注意】数组是多维的,但存储数的内存单元地址是一维的,因此,在存储数组结构之前,需要解决将多维关系映射到一维关系的问题。
【数组特点】 结构固定——维数和维界不变
【数组基本操作】 结初始化、销毁、取元素、修改元素值。一般不做插入删除
所谓压缩存储就是指为多个值相同的元只分配一个存储空间,对零元不分配空间。
【定义】
矩阵中非零元素的个数t,相对矩阵个数s来说较少。
【压缩存储原则】
存储各非零元素的值,行列位置和矩阵行列数
【存储方法】
三元组、十字链表法
【三元组顺序表的优点】
非零元素在表中按行有序存储,便于尽进行依行顺序处理的矩阵运算,又称有序的双下表法。
【三元组顺序表的缺点】
不能随机存取。若按行号取某一行的非零元素,则需从头开始查找。
【十字链表的优点】
它能够灵活的插入因运算而产生的新的非零元素,删除因运算而产生的新的零元素,实现矩阵的各种运算。
广义表(又称列表Lists)是n>=0个元素的有限序列,其中每一个元素或者是原子,或者是广义表。
广义表是线性表的推广
广义表是个递归的概念
表头:第一个元素
表尾:除表头之外的其他元素组成的表
①广义表中的数据元素有相对次序,一个直接前驱,一个直接后继。
②广义表的长度定义为最外层所包含元素的个数。
③广义表的深度定义为该广义表展开后所包含括号的重数。
④广义表可以为其它广义表共享。
⑤广义表可以是一个递归的表。递归的深度是无穷值,长度是有限值
⑥广义表是多层次结构,广义表的元素可以是单元素,也可以是子表
广义表可以看做是线性表的推广,线性表是广义表的特例。
当二维数组的每行或者每列作为子表处理时,数组即为一个广义表。