ds04-数组、串和广义表

合集下载

【C语言版】4第四章串,数组,广义表

【C语言版】4第四章串,数组,广义表

且 T 是非空串。
操作结果:用V替换主串S中出现 的所有与(模式串)T 相等的不重叠的子串。
例如:
假设 S = abcaabcaaabca,T = bca
基 本 操 作
若 V = x, 则经置换后得到 S = axaxaax
若 V = bc, 则经置换后得到 S = abcabcaabc
DestroyString (&S)
基 本 操 作
初始条件:串 S 存在。 操作结果:串 S 被销毁。
StrEmpty(S)
基 本 操 作
初始条件:串S存在。
操作结果:若 S 为空串,则返回TRUE, 否则返回 FALSE。
表示空串,空串的长度为零。
StrCompare(S,T)
基 本 操 作
StrDelete (&S, pos, len)
基 本 操 作
初始条件:串S存在
1≤pos≤StrLength(S)-len+1。
操作结果:从串S中删除第pos个字符 起长度为len的子串。
ClearString
基 本 操 作
(&S)
初始条件:串S存在。 操作结果:将S清为空串。
对于串的基本操作集可以有不同的定义 方法,在使用高级程序设计语言中的串类型 时,应以该语言的参考手册为准。
串的逻辑结构和线性表极为相似,区别 仅在于串的数据对象约束为字符集。
基 本 操 作
串的基本操作和线性表有很大差别。
在线性表的基本操作中,大多以“单个元 素”作为操作对象; 在串的基本操作中,通常以“串的整体” 作为操作对象。
4.1.2 串的表示和实现
串 在程序设计语言中,串只是作为 的 表 示 输入或输出的常量出现,则只需存储 和 实 此串的串值,即字符序列即可。但在 现

数据结构串、数组和广义表知识点总结

数据结构串、数组和广义表知识点总结

数据结构串、数组和广义表知识点总结
数据结构是计算机科学中研究数据如何组织、存储、管理和操作的学科。

三个常见的数据结构串、数组和广义表都是用于存储和操作数据的。

1. 串:
- 串是由0个或多个字符组成的有限序列。

它是一维数组的特例。

- 串的操作包括插入、删除、修改和查找等常见操作。

- 串可以通过数组、链表或动态分配的内存来实现。

2. 数组:
- 数组是一种线性数据结构,它由一组连续的内存空间组成,
存储相同类型的数据。

- 数组的操作包括插入、删除、修改和查找等常见操作。

- 数组的访问时间复杂度为O(1),但插入和删除的时间复杂度
较高。

3. 广义表:
- 广义表是由若干元素组成的有序集合,每个元素可以是原子
或者是一个广义表。

- 广义表可以通过链表来实现,每个节点包含两个指针,一个
指向元素,一个指向下一个节点。

- 广义表的操作包括插入、删除、修改和查找等常见操作。

- 广义表可以表示任意层次的嵌套结构,具有灵活性和扩展性。

总结:
- 串、数组和广义表都是常见的数据结构,用于存储和操作数据。

- 串是字符的有限序列,可以通过数组或链表来实现。

- 数组是一维线性数据结构,存储相同类型的数据,具有常数时间复杂度的访问操作。

- 广义表是由元素组成的有序集合,可以通过链表来实现,能够表示任意层次的嵌套结构。

第4章数组与串第4节广义表

第4章数组与串第4节广义表

// 为原子时输出元素值
if (p->tag==1) cout << ")";
// 为表结点时输出')&)
{ cout << ",";
GLDisp (p->link);
// 递归输出后续表的内容
}
}
}
第4章 数组与串 第4节 广义表
3. 求广义表的长度 所谓广义表的长度是指在广义表中元素个
//p指向广义表的第一个元素
while (p!=NULL)
{ n++;
p=p->link;
}
return n;
}
第4章 数组与串 第4节 广义表
4.广义表的复制 复制一个广义表的算法思想:对于一个广义
表的头结点*p,若为空,则返回空指针;若为子 表,则递归复制子表;否则复制原子结点,然后 递归复制后续表。算法结束返回广义表链表指针。
用字符串变量 s 来表示一个广义表的括号表 达式,从头到尾扫描 s 的每一个符号:
(1)当遇到是左括号,说明是一个表的开始, 则建立一个由 h 指向的表的结点,并用它的dlink 域作为子表的表头指针,进行递归调用;
第4章 数组与串 第4节 广义表
(2)当扫描到一个字母,说明它是一个原子, 则建立一个由h指向的原子结点;
数,由于广义表在同一层次的每个结点是通过 link域链接起来的,所以可把它看做是由link域链 接起来的单链表。这样,求广义表的长度就变成 求单链表的长度了。
第4章 数组与串 第4节 广义表
int GLLength(GLNode *p)
//p为广义表附加头结点的指针
{
int n=0;

第四章数组、串与广义表

第四章数组、串与广义表
• 在高级语言中的一维数组只能按元素的下标 直接存取数组元素的值。
2
一维数组的定义和初始化
#include <iostream.h>
void main ( ) {
int a[3] = { 3, 5, 7 }, *elem, i; //静态数组
for (i = 0; i < 3; i++)
cout << a[i] << endl;
• 特殊矩阵的压缩存储主要是针对阶数很高 的特殊矩阵。为节省存储空间,对可以不 存储的元素,如零元素或对称元素,不再 存储。 对称矩阵 三对角矩阵
14
对称矩阵的压缩存储
• 设有一个 nn 的对称矩阵 A。
• 为节约存储,只存对角线及对角线以上的元 素,或者只存对角线或对角线以下的元素。 前者称为上三角矩阵,后者称为下三角矩阵。
}
多维数组
• 多维数组是一维数组的推广。 • 多维数组的特点是每一个数据元素可以有多
个直接前驱和多个直接后继。 • 数组元素的下标一般具有固定的下界和上界,
因此它比其他复杂的非线性结构简单。 • 例如二维数组的数组元素有两个直接前驱,
两个直接后继,必须有两个下标(行、列) 以标识该元素的位置。
4
二维数组
第四章 数组、串与广义表
• 一维数组与多维数组 • 特殊矩阵 • 稀疏矩阵 • 字符串 • 广义表
1
一维数组
• 定义 数组是相同类型的数据元素的集合,而一维 数组的每个数组元素是一个序对,由下标 (index)和值(value)组成。
• 一维数组的示例
0 1 2 3 4 56 7 8 9
35 27 49 18 60 54 77 83 41 02

《数据结构(C语言)》第4章 串、数组和广义表

《数据结构(C语言)》第4章 串、数组和广义表
Data structures
串的存储与操作
❖ 串的顺序存储与操作 ❖ 1.串的基本操作
(3) 求串长StrLength(s) 返回串s中字符的个数。 算法4.3 求串长度 int StrLength(char s[]) { int len=0;
while(s[len++]!='\0'); return --len; }
4.2(b)所示。当节点大小大于1时,由于串长不一定
是节点大小的整倍数,因此链表中的最后一个节点不
一定全被串值占满,此时通常要补上“#”或其他的
非串值字符(通常,“#”不属于串的字符集,是一个
特殊的符号)。 头指针
S
D
A
E
头指针
S
DATA
STR
UCTU
RE# #
空格符
Data structures
串的存储与操作
charch[CHUNKSIZE];
structChunk *next;
}Chunk;
typedef struct { /*串的链表结构*/
Chunk *head, *tail;/*串的头和尾指针*/
int curlen; /*串的当前长度*/
}LString;
Data structures
串的存储与操作
串(或字符串),是由零个或多个字符组成的有限序列。一般 记为:
s=‘a0a1...an-1’ (n>=0)
其中s是串的名,用单引号括起来的字符序列是串的值;串中字 符的数目n称为串的长度。
❖ 2.空串和空格串
零个字符的串称为空串,它的长度为零。
由一个或多个空格组成的串,称为空格串。它的长度是串中空格字符 的个数。

第4章-串、数组和广义表

第4章-串、数组和广义表

(13) DestroyString(&S)
//串销毁
}ADT String 北京林业大学信息学院
2021年1月9日
6
串的存储结构
顺序存储 链式存储
2021年1月9日
7
顺序存储表示
typedef struct{ char *ch;
int length; }HString;
//若串非空,则按串长分配存储区, //否则ch为NULL //串长度
S :ababcabcacbab

T :abc j
i指针回溯
S :ababcabcacbab
T : abc
S :ababcabcacbab
T : abc
2021年1月9日
13
BF算法设计思想
Index(S,T,pos)
• 将主串的第pos个字符和模式的第一个字符比较, 若相等,继续逐个比较后续字符; 若不等,从主串的下一字符起,重新与模式的第 一个字符比较。
//串的当前长度
}LString;
2021年1月9日
11
串的模式匹配算法
算法目的:
确定主串中所含子串第一次出现的位置(定位) 即如何实现教材P72 Index(S,T,pos)函数
算法种类:
•BF算法(又称古典的、经典的、朴素的、穷举的) •KMP算法(特点:速度快)
2021年1月9日
12
i
BF算法设计思想
(6) StrCopy(&T,S)
//串拷贝
(7) StrEmpty(S)
//串判空
(8) ClearString (&S)
//清空串
(9) Index(S,T,pos)

数据结构-串、数组和广义表课件


BF算法描述(算法4.1)
int Index(Sstring S,Sstring T,int pos){ i=pos; 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算法设计思想(了解)
利用已经部分匹配的结果而加快模式串的滑动速度? 且主串S的指针i不必回溯!可提速到O(n+m)!
i
S=‘a b a b c a b c a c b a b’
T=‘a b c a c’
ii
i
k
S=‘a b a b c a b c a c b a b’
T=‘a b c a c’
//串拷贝
(7) StrEmpty(S)
//串判空
(8) ClearString (&S)
//清空串
(9) Index(S,T,pos)
//子串的位置
(10) Replace(&S,T,V)
//串替换
(11) StrInsert(&S,pos,T)
//子串插入
(12) StrDelete(&S,pos,len)
链式存储表示
head
ABCD
head
A
B
EFGH
I###
C
#define CHUNKSIZE 80 //可由用户定义的块大小 typedef struct Chunk{

四、串、数组和广义表

四、串、数组和⼴义表(内容待完善)知识点串的模式匹配⼜称⼦串定位运算或串匹配。

在匹配中,将主串称为⽬标(串),⼦串称为模式(串)。

BF法(Brute Force):KMP法:串的模式匹配的两种⽅法。

BF法,朴素的串匹配法。

KMP法,尽可能的滑动得更远,利⽤部分的匹配结果。

朴素的模式匹配算法(BF算法)图⽰说明第⼀轮⽐较:第⼆轮⽐较:...... 原理⼀致,省略中间步骤第五轮:第六轮:第⼀轮:⼦串中的第⼀个字符与主串中的第⼀个字符进⾏⽐较若相等,则继续⽐较主串与⼦串的第⼆个字符若不相等,进⾏第⼆轮⽐较第⼆轮:⼦串中的第⼀个字符与主串中第⼆个字符进⾏⽐较......第N轮:依次⽐较下去,直到全部匹配代码实现:(略)BF算法优点:思想简单,直接,缺点:每次字符不匹配时,都要回溯到开始位置,时间开销⼤。

时间复杂度 O((n-m+1)*m) 。

KMP模式匹配算法图⽰说明:从图中,我们可以很容易的发现,因为前⾯的字符,S和T中存在同的元素,所以S不必回溯到S[1]的位置,T也不必回溯到T[0]的位置。

我们就可直接跳过对相同元素的回溯⽐较,直接⽐较S[8]与T[3]。

因此我们构建⼀个next数组储存回溯位置。

KMP算法的思想:假设在模式匹配的进程中,执⾏T[i]和W[j]的匹配检查。

若T[i]=W[j],则继续检查T[i+1]和W[j+1]是否匹配。

next数组两种求法(1)第⼀种求法:根据前⼀个字符的next值求初始化:代码实现:1 char t[]={"ababaabab"};2 int Len=strlen(t);34 int i = 0, j = -1;5 int next[len];6 next[0]=-1;7 while (i < len - 1) {8 if ((j == -1) || t[i] == t[j]) {9 ++i, ++j;10 next[i] = j;11 }else{12 j = next[j];13 }14 }1516 for(i=0;i<len;i++)17 {printf("next[%d]->%d\n",i,next[i])}(2)第⼆种求法:根据最⼤公共元素长度求的求法))next数组优化(nextval的求法当⼦串中有多个连续重复的元素,例如主串 S=“aaabcde” ⼦串T=“aaaaax” 在主串指针不动,移动⼦串指针⽐较这些值,其实有很多⽆⽤功,因为⼦串中5个元素都是相同的a,所以我们可以省略掉这些重复的步骤。

串 数组 广义表 题目

串数组广义表题目
我不确定你想要什么类型的题目,但我可以给你一些与串、数组和广义表相关的题目作为参考:
1. 串:编写一个程序,从用户输入的字符串中查找给定的子串,并返回它在原始字符串中的位置。

2. 数组:编写一个程序,找到给定数组中的最大值和最小值,并计算它们的差值。

3. 广义表:实现一个广义表的数据结构,并编写相关的操作函数,如插入、删除、获取子表等操作。

4. 串:编写一个程序,判断给定的两个字符串是否是Anagram,即它们包含的字符相同,但顺序不同。

5. 数组:编写一个程序,对给定的数组进行排序,可以选择不同的排序算法实现。

6. 广义表:编写一个程序,将一个广义表展开为一个一维的数组。

7. 串:编写一个程序,计算给定字符串中各个字母出现的频率。

8. 数组:编写一个程序,查找给定数组中第K个最大/最小的
元素。

9. 广义表:编写一个程序,将一个普通的表达式字符串解析为一个广义表,并计算其值。

这些题目可以帮助你更深入地理解和应用串、数组和广义表的相关知识。

你可以根据自己的兴趣和能力选择其中一个或多个来实现。

第四章串、数组和广义表PPT课件

第14页/共68页
4.1.4 串的存储结构
• 串的链式存储表示 串的链式存储结构和线性表的串的链式存储结构类似,采用单链表来存储串,结
点的构成是:
• data域:存放字符,data域可存放的字符个数称为结点的大小; • next域:存放指向下一结点的指针。
first
a
b
g∧
• 若每个结点仅存放一个字符,则结点的指针域就非常多,造成系统空间浪费,为
基本思想:从主串S的第一个字符开始和模式T 的第一个字符进行比较,若相等,则继续比较两者的后续字符; 否则,从主串S的第二个字符开始和模式T 的第一个字符进行比较,重复上述过程,直到T 中的字符全部比 较完毕,则说明本趟匹配成功;或S中字符全部比较完,则说明匹配失败。
• 模式匹配问题的特点: • ⑴ 算法的一次执行时间不容忽视:问题规模通常很大,常常需要在大量信息中进行匹配; • ⑵ 算法改进所取得的积累效益不容忽视:模式匹配操作经常被调用,执行频率高。
第26页/共68页
4.1.4 匹配模式——BP算法
例:主串S="ababcabcacbab",模式T="abcac"
i
第 ababcabcacbab
5

abcac
j
i=5,j=1失败; i“回溯”到6,j回溯到1
第27页/共68页
4.1.4 匹配模式——BP算法
例:主串S="ababcabcacbab",模式T="abcac"
• 定长顺序存储表示:将串定义成字符数组,利用串名可以直接访问串 值。用这种表示方式,串的存储空间在编译时确定,其大小不能改变。
• 堆分配存储方式:仍然用一组地址连续的存储单元来依次存储串中的 字符序列,但串的存储空间是在程序运行时根据串的实际长度动态分 配的。
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

} return b;
}
快速转置算法


设矩阵三元组表总共有 t 项,上述算法的 时间代价为 O ( n* t )。 若矩阵有 200 行,200 列,10,000 个非零 元素,总共有 2,000,000 次处理。


为加速转置速度,建立辅助数组 rowSize 和 rowStart,记录矩阵转置后各行非零元 素个数和各行元素在转置三元组表中开始 存放位置。 扫描矩阵三元组表,根据某项列号,确定 它转置后的行号, 查 rowStart 表, 按查到 的位置直接将该项存入转置三元组表中
稀疏矩阵的快速转置
template <class Type> SparseMatrix<Type>& SparseMatrix<Type> :: FastTranspos (SparseMatrix<Type>& a) { int *rowSize = new int[a.Cols]; int *rowStart = new int[a.Cols]; SparseMatrix<Type> b ( a.Cols, a.Rows ); b.Rows = a.Cols; b.Cols = a.Rows; b.Terms = a.Terms; if ( a.Terms > 0 ) { for (int i = 0; i < Cols; i++) rowSize[i] = 0;
稀疏矩阵的转置
template <class Type> SparseMatrix<Type>& SparseMatrix<Type> :: Transpose (SparseMatrix<Type>& a) { SparseMatrix<Type> b (a.Cols, a.Rows); b.Rows = a.Cols; b.Cols = a.Rows; b.Terms = a.Terms; //转置矩阵的列数,行数和非零元素个数 if ( a.Terms > 0 ) { int CurrentB = 0; //转置三元组表存放指针
行优先存放: 设数组开始存放位置 LOC( 0, 0 ) = a, 每 个元素占用 d 个存储单元 LOC ( j, k ) = a + ( j * m + k ) * d

二维数组
a[0][m 1] a[1][m 1] a[2][m 1] a[n 1][m 1]
n n 1 *l a i m i j k n j 1 k j 1
特殊矩阵
一般矩阵:无特殊规律,用二维数组存储 特殊矩阵:元素分布有一定规律的矩阵,如 对角矩阵、带状矩阵、对称矩阵,若采用针 对性的特殊方法存储,可节省大量空间。 对角矩阵:aij=0(若i≠j),用一维数组存储主 对角线元素 对称矩阵:aij=aji,只需存储对角线和对角线 以下的元素(下三角存储),或对角线和对 角线以上的元素(上三角存储)。
稀疏矩阵的转置



一个 mn 的矩阵 A,它的转置矩阵 B 是 一个 nm 的矩阵,且 A[i][j] = B[j][i]在稀疏矩阵的三元组表中,非零矩阵元素 按行存放。当行号相同时,按列号递增的 顺序存放。 稀疏矩阵的转置运算要转化为对应三元组 表的转置。
for ( i = 0; i < Terms; i++ ) rowSize[smArray[i].col]++; rowStart[0] = 0; for ( i = 1; i < a.Cols; i++ ) rowStart[i] = rowStart[i-1]+rowSize[i-1]; for ( i = 0; i < a.Terms; i++ ) { int j = rowStart[a.smArray[i].col]; b.smArray[j].row = a.smArray[i].col; b.smArray[j].col = a.smArray[i].row; b.smArray[j].value = a.smArray[i].value; rowStart[a.smArray[i].col]++; }
行 列 值 (row) (col) (value) 0 4 91 1 1 11 2 5 28 3 0 22 3 2 -6 5 1 17 5 3 39 6 0 16
用三元组表表示的稀疏矩阵及其转置
行 列 值 (row) (col) (value) 0 3 22 0 6 15 1 1 11 1 5 17 2 3 -6 3 5 39 4 0 91 5 2 28 行 列 值 (row) (col) (value) 0 4 91 1 1 11 2 5 28 3 0 22 3 2 -6 5 1 17 5 3 39 6 0 16
稀疏矩阵 (Sparse Matrix)
非零元素个数远远少于矩阵元素个数
0 0 0 22 0 0 15 0 0 17 0 0 11 0 0 0 0 6 0 0 0 0 0 39 0 0 0 0 91 0 0 0 0 0 0 0 0 28 0 0 0 0
页向量 下标 i 行向量 下标 j 列向量 下标 k
数组的连续存储方式

一维数组
LOC(i) =
0 1 2
a,
3 4
i=0
5 6 7 8 9
LOC(i-1)+l = a+i*l, i > 0
a 35 27 49 18 60 54 77 83 41 02
l l l l l l l a+i*l l l l

三维数组
各维元素个数为 m1, m2, m3
下标为 i1, i2, i3的数组元素的存储地址:
(按页/行/列存放) LOC ( i1, i2, i3 ) = a + ( i1* m2 * m3 + i2* m3 + i3 ) * l
前i1页总
第i1页的 第 i2 行前 i3 元素个数 前i2行总 列元素个数
[0] [1] [2] [3] [4] [5] [6] [7]
[0] [1] [2] [3] [4] [5] [6] [7]
稀疏矩阵转置算法思想

设矩阵列数为 Cols,对矩阵三元组 表扫描Cols 次。第 k 次检测列号为 k 的项。

第 k 次扫描找寻所有列号为 k 的项, 将其行号变列号、列号变行号,顺次 存于转置矩阵三元组表。
稀疏矩阵
template<class Type> struct Trituple { //三元组 int row, col; //非零元素行号/列号 Type value; //非零元素的值 }; template <class Type> class SparseMatrix { //稀疏矩阵类定义
稀疏矩阵
0 0 0 0 91 0 0 11 0 0 0 0 0 22 0 0 15 [0] 0 0 0 17 0 [1] [2] 0 6 0 0 0 [3] 0 0 0 39 0 [4] [5] 0 0 0 0 0 [6] 28 0 0 0 0 [7]
A 67
稀疏矩阵的定义




设矩阵 Amn 中有 t 个非零元素,若 t 远 远小于矩阵元素的总数 mn,则称矩阵 A 为稀疏矩阵。 为节省存储空间,应只存储非零元素。 非零元素的分布一般没有规律,应在存 储非零元素时,同时存储该非零元素的 行下标 row、列下标 col、值 value。 每一个非零元素由一个三元组唯一确定: ( 行号 row, 列号 col, 值 value )
a[0][1] a[0][0] a[1][1] a[1][0] a a[2][0] a[2][1] a[n 1][0] a[n 1][1]
列优先存放: 设数组开始存放位置 LOC( 0, 0 ) = a, 每 个元素占用 d 个存储单元 LOC ( j, k ) = a + ( k * n + j ) * d
int Rows, Cols, Terms; //行/列/非零元素数 Trituple<Type> smArray[MaxTerms]; public: //三元组表 SparseMatrix (int MaxRow, int Maxcol); SparseMatrix<Type>& Transpose (SparseMatrix<Type>&); //转置 SparseMatrix<Type>& Add (SparseMatrix <Type> a, SparseMatrix<Type> b); //相加 SparseMatrix<Type>& Multiply(SparseMatrix <Type> a, SparseMatrix<Type> b); //相乘 };
元素个数

n 维数组
各维元素个数为 m1, m2, m3, …, mn
下标为 i1, i2, i3, …, in 的数组元素的存储 地址:
LOC ( i1, i2, …, in ) = a + ( i1*m2*m3*…*mn + i2*m3*m4*…*mn+ + ……+ in-1*mn + in ) * l
n阶对称方阵:元素总数为n2 ,上(下)三角阵 的元素共有: n + (n-1) + (n-2) + …… + 2 + 1 = n(n+1) / 2 一维数组下三角存储:Loc(i,j)=Loc(j,i)=(j+1)*j/2+i a00 a10 a11 … an-1,0 an-1,1 … an-1,n-1 一维数组上三角存储:Loc(i,j)=(2n-j-1)*j/2+i a00 a01 a02 … a0,n-1 a1,1 a1,2 … a1,n-1 a2,2 … an-1,n-1
相关文档
最新文档