串、数组和广义表
{
串:
顺序存储串和链式存储串
数组:
顺序存储串和链式存储串
广义表:
顺序存储广义表和链式存储广义表
}
串(String)
{
串的定义:
零个或多个字符组成的有限序列
串的表示:
顺序存储串
{
顺序存储串表示:
与线性表的基本一致,区别仅在于限制了元素类型为串
顺序存储结构串的实现
{
顺序存储结构的类型定义:
typedef struct
{
char *ch; //定义数据元素的类型为字符类型
int length; //定义串长
}SqString;
}
}
链式存储串
{
链式存储串表示:
顺序存储结构串的实现:
链串的数据类型定义
#define CHUNKSIZE 80 //可由用户定义的块大小
typedef struct Chunk{
char ch[CHUNKSIZE];
struct Chunk *next;
}Chunk;
typedef struct{
Chunk *head,*tail; //串的头指针和尾指针
int curlen; //串的当前长度
}LString;
}
串的重要实现:串的匹配算法 Index(S,T,pos)
(1)BF算法(朴素算法)
int Index(SqString S,SqString T,int pos)
{
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;
return 0; //定位条件错误,查找失败
}
算法评价(n为主串长度,m为子串长度):
总次数为:(n-m)*m+m=(n-m+1)*m,若m<<n,则算法复杂度O(n*m)
(2)KMP算法(快速算法)
next函数:
KMP图示:
void get_next(SqString T, int &next[])
{
i=j=1;next[1] = 0; j = 0; //初始化数组(数组范围1-T.length),T的指针j=0
while( i<T.length){
if(j==0 || T[i] == T[j]){ //其它情况j=0和max k
++i; ++j;
next[i] = j;
}
else
j = next[j];
}
}
int Index_KMP (SqString S,SqString T, int pos)
{
i= pos,j =1;
while (i<S.length && j<T.length) {
if (j==0 || S[i]==T[j]) { i++;j++; }
else
j=next[j]; /*i不变,j后退*/
}
if (j>T.length) return i-T.length; /*匹配成功*/
else return 0; /*返回不匹配标志*/
}
KMP算法的时间复杂度
设主串s的长度为n,模式串t长度为m,在KMP算法中求next数组的时间复杂度为O(m),在后面的匹配中因主串s的下标不减即不回溯,比较次数可记为n,所以KMP算法总的时间复杂度为O(n+m)
next函数的改进
void get_nextval(SqString T, int &nextval[])
{
i= 1; nextval[1] = 0; j = 0;
while( i<T.length){
if(j==0 || T[i] == T[j]){
++i; ++j;
if(T[i] != T[j]) nextval[i] = j;
else nextval[i] = nextval[j];
}
else j = nextval[j];
}
}
}
数组
{
数组与高级语言的数组的区别:
高级语言中的数组是顺序结构,数据结构中的数组既可以是顺序的,也可以是链式结构;
数组(以低维为例)
{
一维数组
二维数组(行序优先和列序优先)
设数组a[n][m],行序优先,开始存放位置 LOC( 0, 0 ) = a ,则
LOC ( j, k ) = a + j * m + k
数组与矩阵
{
特殊矩阵的压缩存储
{
压缩存储:
若多个数据元素的值都相同,则只分配一个元素值的存储空间,且零元素不占存储空间。
特殊矩阵:
对称矩阵,对角矩阵,三角矩阵,稀疏矩阵等。
*稀疏矩阵是矩阵中非零元素的个数较少(一般小于5%)
特殊矩阵的压缩存储:数组下标(i,j)<-->存储地址
(1)对称矩阵
(2)三角矩阵
(3)对角矩阵
在n*n的方阵中,非零元素集中在主对角线及其两侧共L(奇数)条对角线的带状区域内 — L对角矩阵。
}
}
}
}
广义表
{
广义表:
n ( >=0 )个表元素组成的有限序列,记作LS = (a0, a1, a2, …, an-1)
* LS是表名,ai是表元素,它可以是表 (称为子表),可以是数据元素(称为原子)。 *n为表的长度。n = 0 的广义表为空表。
广义表与线性表的区别?
(1)线性表的成分都是结构上不可分的单元素
(2)广义表的成分可以是单元素,也可以是有结构的表
(3)线性表是一种特殊的广义表
(4)广义表不一定是线性表,也不一定是线性结构
广义表的基本运算
(1)求表头GetHead(L):非空广义表的第一个元素,可以是一个单元素,也可以是一个子表
(2)求表尾GetTail(L):非空广义表除去表头元素以外其它元素所构成的表。表尾一定是一个表
}