串、多维数组与广义表的那些事

本文详细介绍了数据结构中的串、数组和广义表。串包括其定义、基本操作和不同存储方式,如定长顺序串、堆串和链串,并讲解了模式匹配算法BF和KMP。数组部分探讨了一维和二维数组的存储优化,如对称矩阵、三角矩阵和稀疏矩阵的压缩存储。最后,广义表的概念、结构以及子表的表示也被阐述。
摘要由CSDN通过智能技术生成

 🌞欢迎来到数据结构的世界 
🌈博客主页:卿云阁

💌欢迎关注🎉点赞👍收藏⭐️留言📝

🌟本文由卿云阁原创!

🌠本阶段属于筑基阶段,希望各位仙友顺利完成突破

📆首发时间:🌹2021年2月16日🌹

✉️希望可以和大家一起完成进阶之路!

🙏作者水平很有限,如果发现错误,请留言轰炸哦!万分感谢!


目录

0️⃣串

1️⃣ 数组

2️⃣广义表

 0️⃣✨✨✨✨✨✨ 

串(string)(或字符串)是由零个或多个字符组成的有限序列,

一般记为:            S="a1 a2 …… an" (n≥0) 

模式匹配:求子串在主串中的起始位置称为子串定位或模式匹配。

ADT String{	
数据对象D:D={ai|ai∈ElemSet,i=1,2, …,n,n≥0}
数据关系R:R={<ai-1,ai>| ai-1,ai∈D,i=2,3, …,n }
基本操作P:
串赋值StrAssign(&S,chars):S是一个串变量,chars是一个串常量。将chars的值赋给串S;
串比较StrCompare(S,T):若串变量S>串变量T,则返回值>0;若S=T,则返回值为0;若S<T,则返回值<0;
求串长StrLength(S):返回S中元素的个数;
串联接Concat(&S,T1,T2):用S返回T1和T2联接而成的新串,如:T1="xyz",T2="abc",则Concat (&S,T1,T2)= "xyzabc",注意Concat (S,T1,T2)≠Concat (S,T2,T1);
求子串SubString(&T,S, pos, len):1≤pos≤StrLength(S),0≤len≤StrLength(S)-pos+1,用T返回S中的第pos个字符起长度为len的子串;
判断空串StrEmpty(S):若S为空串,则返回TRUE,否则返回FALSE;
串复制StrCopy(&T,S):将串S复制到串T;
串清空ClearString(S):将S置空串;
串定位Index(S,T,pos):串S和T存在,T是非空串,1≤pos≤StrLength(S),若T是S的子串,返回T在S中第一次出现的位置,否则返回0;
串置换Replace(&S,T,V):串S,T和V存在,T是非空串,用V替换主串S中出现的所有与T相等的不重叠的子串。例如:设S="bbabbabba",T="ab",V="a",则Replace(&S,T,V)的结果是S="bbababa";
串插入StrInsert(&S,pos,T):1≤pos≤StrLength(S)+1,在串S的第pos个字符之前插入串T;
串删除StrDelete(&S,pos,len): 1≤pos≤StrLength(S)-len+1,从串S中删去第pos字符起长度为len的子串;
串销毁DestroyString(&S) :串S被销毁,并回收串空间;
}ADT String

串的表示和实现

串的表示有三种方式:定长顺序串、堆串和链串

串的定长顺序存储表示

方法一

#define MAXSIZE 100
typedef struct
{ char ch[MAXSIZE];//字符数组存储串值
  int length;//整型变量表示串的长度
}SString;

 方法二

定义字符数组 s[MAXSIZE+1]; 用串数组的第一个单元s[0]存放串的实际长度,串值存放在s[1]~s[MAXSIZE]中,用字符'\0'作为串的结束符。这种方法字符的序号与存储位置是一致的。 数据类型描述如下:

#define MAXSIZE 100  //用户可在100以内定义最大串长
typedef char SString[MAXSIZE+1];  //0号单元存放串的实际长度

 串的堆分配存储表示

typedef struct
{ 
  char *ch;    //若是非空串,则按串长分配存储区,否则ch为NULL
  int length;  //串的实际长度
}HString;

串的链式存储结构 

串的链式数据类型中结点大小为1的结点描述如下:
typedef struct Node
{ char data;
  struct Node *next;
}LinkString;

 

串的模式匹配算法 

1. BF算法

将主串S的第一个字符和模式T的第1个字符比较,若相等,继续逐个比较后续字符;若不等,从主串S的下一字符起,重新与T第一个字符比较。直到主串S的一个连续子串字符序列与模式T相等。返回值为S中与T匹配的子序列第一个字符的序号,即匹配成功。否则,匹配失败,返回值0

int Index(SString S,SString T)
{ int i=1,j=1;
  while(i<=S[0]&&j<=T[0])
	{if(S[i]==T[j])	
	   {  i++;j++; }     //继续比较后继字符
	  else   {  i=i-j+2;j=1; }   //指针后退重新开始匹配
	}
  if (j>T[0]) return i-T[0];
  else return 0;
}

 KMP算法

每当一趟匹配过程中出现字符比较不等时,不需回溯i指针,而是利用已经得到的“部分匹配”的结果将模式向右“滑动”尽可能远的一段距离后,继续进行比较。

本质在于j指针在下一次比较中回到哪一个位置。

2和3一样,1和2已经比较成功,所以1和3不需要比较。 

 

 a b c d 

前缀:

a

a b

a b c

后缀

d

c d

b c d


1️⃣✨✨✨ 数组✨✨✨

1.一维数组

 A[n]或A=( a0,al,…ai,…,an-1)。

2.二维数组 

m行n列的二维数组 Amn可以表示为

 

矩阵的压缩存储 

在数值分析过程中经常遇到一些比较特殊的矩阵,如对称矩阵、三角矩阵、带状矩阵和稀疏矩阵等。为了节省存储空间并且加快处理速度,下面讨论这些特殊矩阵的存储方法。

1.对称矩阵

对称矩阵是一个n阶方阵。其元素满足:aij=aji  (0≤i,j≤n-1)。 对称矩阵中的元素是关于主对角线对称的,因此在存储时只存储上三角或下三角(包括对角线),使得对称的元素共享一个存储空间。这样,n阶矩阵中的n×n个元素就可以被压缩到 n(n+1)/2 个元素的存储空间中

以行优先顺序对面上的对称矩阵存储其下三角,存储序列为: 2,4,0,1,8,1,3,6,2,0,7,1,6,5,3

三角矩阵

⑴下三角矩阵 下三角矩阵与对称矩阵的压缩存储类似,不同之处在于存储完下三角中的元素以后,紧接着存储对角线上方的常量,因为是同一个常数,只需存储一个即可。数组下标与元素之间存在着如下对应关系:

⑵上三角矩阵 对于上三角矩阵,第一行存储n个元素,第二行存储n-1个元素,依次类推,aij的前面有i行,共存储n+(n-1)+…+(n-(i-1))=i(2n-i+1)/2个元素,在i行,aij前有j-i个元素,因此数组下标与元素之间存在着如下对应关系:

对角矩阵 

A中第0行和第n-1行都只有两个非零元素,其余各行均为3个非零元素。对于不在第0行的非零元素aij,在它前面存储了矩阵的前i行元素,这些元素共2+3(i-1)个。若aij是本行中要存储的第1个非零元素,则k=2+3(i-1),此时,j=i-1,即k=2i+i-1=2i+j;若aij是本行中要存储的第2个非零元素,则k=2+3(i-1)+1=3i,此时,j=i,即k=2i+i=2i+j;若aij是本行中要存储的第3个非零元素,则k=2+3(i-1)+2=3i+1,此时,j=i+1,即k=2i+i+1=2i+j。因此,非零元素aij与数组b的下标之间存在着如下对应关系:k=2i+j。

稀疏矩阵 

如果矩阵中有很多零元素,即零元素的个数远远大于非零元素的个数时,称该矩阵为稀疏矩阵。

有两种常用的存储稀疏矩阵的方法:三元组表示法和十字链表法。

三元组表示法

#define NUM 100     	//矩阵中非零元素最大个数
typedef struct      	//三元组结构
{ int r, c;         		//行号和列号
   ElemType d;       	//元素值
}TupType;           	//三元组定义
typedef struct   
{ int rows,cols,nums;   //矩阵行数值、列数值、非零元素个数
   TupType data[NUM]; //三元组表
}TSMatrix;               	//三元组表定义

 2.十字链表

结点中三元组(i,j,v)表示非零元素所在的行、列和值,两个链域:行指针域(right)用来指向本行中下一个非零元素;列指针域(down)用来指向本列中下一个非零元素。 稀疏矩阵中同一列的所有非零元素通过down指针域链接成一个循环列链表,同一行的所有非零元素通过right指针域链接成一个带表头结点的循环行链表。因此,每个非零元素aij既是第i行循环链表中的一个结点,又是第j列循环链表中的一个结点,就像一个十字交叉路口,故称其为十字链表。


2️⃣✨✨✨ 广义表✨✨✨

广义表是n(n≥0)个元素a1,a2,a3,…,an的有限序列,

记作LS=(a1,a2,a3,…,an),

其中ai是LS的成员,可以是原子项,也可以是一个广义表(子表)。

LS是广义表的名字,n为它的长度。若ai是广义表,则称它为LS的子表

。当广义表LS非空时,称第一个元素a1为LS的表头(Head),称其余元素组成的表(a2,a3,…,an)是LS的表尾(Tail)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

卿云阁

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

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

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

打赏作者

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

抵扣说明:

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

余额充值