一、串
内容受到限制的线性表
1. 定义
串由0个或者多个任意字符组成的有限序列
n=0为空串
s= “fdasfads”
术语
子串:
- 一个串当中任意连续字符组成子序列
- 真子串不包含自身
"asdf";
//子串
“” “abc” "ab" "abcdf"...
主串:
- 字符位置:字符在序列中序号为该字符在串当中位置
- 子串的位置: 子串第一个字符在主串当中的位置
- 空格串: 由若干个空格组成字符
串相等,两个串长度相等,并且各个对应位置的字符都需要相同,这两个字符串才会相等。
所有的空串都是相等的
2. 串类型定义和存储结构运算
数据对象属于全字符
数据关系依然是线性表
串的元素逻辑关系和线性表相同,串也可以采用线性表相同的存储结构
<a name="XH7UD"></a>
### 链式存储结构
- **操作方便,但是存储密度较低**
- **串所占的存储/实际分配的存储**
- 可以将多个字符存放在一个节点当中,以克服其缺点
![image.png](https://cdn.nlark.com/yuque/0/2021/png/12423141/1638520408395-64fcb570-8740-4e0c-a8de-414201bcc033.png#clientId=ue5495cea-29ed-4&from=paste&height=163&id=u7ca4b18b&margin=%5Bobject%20Object%5D&name=image.png&originHeight=326&originWidth=1362&originalType=binary&ratio=1&size=108188&status=done&style=none&taskId=uffd21dde-b9c9-42f3-9d67-4094cc4f88c&width=681)<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/12423141/1638520720633-435661f7-f251-4cf1-9173-b023f33a3893.png#clientId=ue5495cea-29ed-4&from=paste&height=175&id=u257425f3&margin=%5Bobject%20Object%5D&name=image.png&originHeight=350&originWidth=1520&originalType=binary&ratio=1&size=144283&status=done&style=none&taskId=u4d38eb73-2c24-413d-ad95-4482a17319e&width=760)
```c
//块链串
#define CHUNKSIZE 80
typedef struct Chunk{
char ch[CHUNKSIZE];
struct Chunk *next;
}Chunk;
typedef struct {
Chunk *head,*tali; //头尾
int curLen; //当前长度
}LString;
实际当中顺序存储结构会用的更多
3. 串的模式匹配算法
int index_BF(SqStr S,SqStr T,int pos){
int i =pos; //从哪个开始查找
int j = 0;
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算法
二、数组
1. 定义
按一定格式排列起来的具有相同类型的元素集合
- 一维数组,若线性表中数据元素为非结构的简单的元素,可以称为一维数组
一维数组的逻辑结构: 线性结构
int num[5]={0,1,2,3,4};
二维数组: 若干行,若干列
typedef elemtype arr1[5][8]
typedef elemtype2 arr2[2]
typedef arr2 arr3[8] <#new#>
三维数组
- 若n-1维数组中元 线性结构是数据结构的特例
数组结构又是线性表的扩展
- 若n-1维数组中元 线性结构是数据结构的特例
-
2. 抽象数据类型
当 n = 2(二维数组)
- b1:第一维(长度)的长度 b2:第二维(列数)的长度
- aj1j2:
- j1就是一维数组的下标(0<=j1<=b1-1)
- j2就是二维数组的下标(0<=j2<=b1-1)
3. 顺序存储
- 数组特点结构固定,维数和操作不会改变
数组基本操作:初始化销毁取出修改,一般不会插入和删除
一般使用顺序来存储!!
例题: 每个元素占用四个字节,假设a[0]在2000单元,那么a[3] = a[0]+(4*3)
(i)*L+a(第一个元素的单元地址)
两种存储方式
- 行优先
- 列优先
广义表
概述
LS = (a1,a2…an)
表尾
除了表头之外其他元素组成的表
记作tail(LS)=(a2,….,an)
表尾不是最后的元素,而是一个子表
广义表的性质
- 广义表元素有次序,一个直接前驱和后继
- 广义表的长度定义为最外层所包含的元素个数
- 广义表的深度定义为广义表展开后所含括号的重数。
- 原子的深度为零
- ‘空表的深度’=1
- 广义表可以被其他的表共享
- 广义表也可以是递归表 ,深度无穷,长度有限
- 广义表是一种多层次的结构
广义表的常见运算
- 求表头GetHead()
- 表头可能是原子也可能是表
- 表尾GetTail()
- 表尾一定是一个表