第四章字符串和多维数组
本章的基本内容是:
串的存储结构及模式匹配算法数组的逻辑结构特征
数组的存储结构及寻址方法特殊矩阵和稀疏矩阵的压缩存储方法字符串的定义
字符串:零个或多个字符组成的有限序列。简称串串长度:串中所包含的字符个数。
空格串:只包含空格的串。
空串:长度为0的串,记为:" “。
非空串通常记为:
S=” s1 s2 …… sn "
其中:S是串名,双引号是定界符,双引号引起来的部分是串值,si(1≤i≤n)是一个任意字符。
字符串的定义
串的数据对象约束为某个字符集。
•微机上常用的字符集是标准ASCII码,由 7 位二进制数表示一个字符,总共可以表示 128 个字符。扩展ASCII码
由 8 位二进制数表示一个字符,总共可以表示 256 个字符,足够表示英语和一些特殊符号,但无法满足国际需要。
•Unicode由 16 位二进制数表示一个字符,总共可以表示
216个字符,即6万5千多个字符,能够表示世界上所有语言的所有字符,包括亚洲国家的表意字符。为了保持兼
容性,Unicode字符集中的前256个字符与扩展ASCII码完全相同。
字符串的定义
子串:串中任意个连续的字符组成的子序列。
主串:包含子串的串。
子串的位置:子串的第一个字符在主串中的序号。
S1="ab12cd " //长度为6的串
S2= “ab12” //长度为4的串
S3= “26138” //长度为5的串
S4=“ab12φ” //长度为5的串
S5= “” //空串,长度为0
S6= "φφφ " //含3个空格的空格串,长度为3
字符串的定义
串的比较:通过组成串的字符之间的比较来进行的。给定两个串:X="x1x2…xn"和Y=“y1y2…ym”,则:
- 当n=m且x1=y1,…,xn=ym时,称X=Y;
- 当下列条件之一成立时,称X<Y:
⑴ n<m且xi=yi(1≤ i≤n);
⑵存在k≤min(m,n),使得xi=yi(1≤i≤k-1)且xk<yk。
例:S1="ab12cd ",S2=“ab12”,S3="ab13“
“串值大小”是按“词典次序”进行比较的。
串的抽象数据类型定义
⑴ StrLength (s):求串s的长度。
⑵ StrAssign (s1, s2):赋值,将s2的值赋值给串s1。
⑶ StrConcat (s1, s2, s):连接,将串s2放在串s1的后面连接成一个新串s。
⑷ SubStr (s, i, len):求子串,返回从串s的第i个字符开始取长为 len 的子串。
⑸ StrCmp (s1, s2):串比较,若s1=s2,返回0;若 s1<s2, 返回-1;若s1>s2, 返回1。
⑹ StrIndex (s, t):定位,返回子串t在主串s中首次出现的位置。若t不是s的子串,则返回0。
串的抽象数据类型定义
⑺ StrInsert (s, i, t):插入,将串t插入到串s中的第i个位置。
⑻ StrDelete (s, i, len):删除,在串s中删除从第i个字符开始的连续len个字符。
⑼ StrRep (s, t, r):替换,在串s中用串r替换所有与串t 相等的子串。
与其他数据结构相比,串的操作对象有什么特点?
串的操作通常以串的整体作为操作对象。
串的抽象数据类型定义
求子串操作SubStr(s, i, len)示例 i = 3, len = 3 i = 7, len = 4
a b c d e f g e
a b c d e f g e
空串
c d e g e
串的存储结构
顺序串:用数组来存储串中的字符序列。 如何改造数组实现串的顺序存储?
(1)非压缩形式。
a b c d e f g
串的存储结构
顺序串:用数组来存储串中的字符序列。 如何改造数组实现串的顺序存储?
(1) 非压缩形式。
启示:时空权衡!
(2) 压缩形式。
串的存储结构 如何表示串的长度?方案1:用一个变量来表示串的实际长度。
0 1 2 3 4 5 6 … … Max-1
a b c d e f g 空 闲 7
串的存储结构
如何表示串的长度?
方案1:用一个变量来表示串的实际长度。
方案2:在串尾存储一个不会在串中出现的特殊字符作为串的终结符,表示串的结尾。
0 1 2 3 4 5 6 7 … … Max-1
a b c d e f g \0 空 闲
串的存储结构
如何表示串的长度?
方案1:用一个变量来表示串的实际长度。
方案2:在串尾存储一个不会在串中出现的特殊字符作为串的终结符,表示串的结尾。
方案3:用数组的0号单元存放串的长度,从1号单元开始存放串值。
0 1 2 3 4 5 6 7 … … Max-1
7 a b c d e f g 空 闲
串的存储结构
链接串:用链接存储结构来存储串。
如何改造链表实现串的链接存储?
(1)非压缩形式
first
串的存储结构
链接串:用链接存储结构来存储串。
如何改造链表实现串的链接存储?
(1) 非压缩形式
启示:时空权衡!
e f g ∧
(2) 压缩形式first
模式匹配
模式匹配:给定主串S="s1s2…sn"和模式T=“t1t2…tm”,在S中寻找T 的过程称为模式匹配。如果匹配成功,返回T 在S中的位置,如果匹配失败,返回0。
假设串采用顺序存储结构,串的长度存放在数组的
0号单元,串值从1号单元开始存放。模式匹配——BF算法(Brute Force算法)基本思想:从主串S的第一个字符开始和模式T 的第一个字符进行比较,若相等,则继续比较两者的后续字符;否则,从主串S的第二个字符开始和模式T 的第一个字符进行比较,重复上述过程,直到T 中的字符全部比较完毕,则说明本趟匹配成功;或S中字符全部比较完,则说明匹配失败。
模式匹配问题的特点:
⑴算法的一次执行时间不容忽视:问题规模通常很
大,常常需要在大量信息中进行匹配;
⑵算法改进所取得的积累效益不容忽视:模式匹配操作经常被调用,执行频率高。
模式匹配——BF算法
模式匹配——BF算法
模式匹配——BF算法
例:主串S=“ababcabcacbab”,模式T=“abcac”
i i i
第 a b a b c a b c a c b a b
1 趟 a b c a c
i=3,j=3失败;
j j j i回溯到2,j回溯到1
模式匹配——BF算法
例:主串S=“ababcabcacbab”,模式T=“abcac”
i
a b a b c a b c a c b a b
第
1
i=3,j=3失败; i回溯到2,j回溯到1
趟 a b c a c
j
模式匹配——BF算法
例:主串S=“ababcabcacbab”,模式T=“abcac”
模式匹配——BF算法
例:主串S=“ababcabcacbab”,模式T=“abcac”
i
a b a b c a b c a c b a b
第
i=2,j=1失败
i回溯到3,j回溯到1
2 趟 a b c a c
j
模式匹配——BF算法
例:主串S=“ababcabcacbab”,模式T=“abcac”
模式匹配——BF算法
例:主串S=“ababcabcacbab”,模式T=“abcac”
i
a b a b c a b c a c b a b
第
3
i=7,j=5失败
i回溯到4,j回溯到1
趟 a b c a c
j
模式匹配——BF算法
例:主串S=“ababcabcacbab”,模式T=“abcac”
模式匹配——BF算法
例:主串S=“ababcabcacbab”,模式T=“abcac”
i
a b a b c a b c a c b a b
第
4
i=4,j=1失败
i回溯到5,j回溯到1
趟 a b c a c
j
模式匹配——BF算法
例:主串S=“ababcabcacbab”,模式T=“abcac”
模式匹配——BF算法
例:主串S=“ababcabcacbab”,模式T=“abcac”
i
a b a b c a b c a c b a b
第
5 趟
模式匹配——BF算法
例:主串S=“ababcabcacbab”,模式T=“abcac”
模式匹配——BF算法
- 在串S和串T中设比较的起始下标i和j;
- 循环直到S或T的所有字符均比较完;
2.1 如果S[i]=T[j],继续比较S和T的下一个字符;
2.2 否则,将i和j回溯,准备下一趟比较; - 如果T中所有字符均比较完,则匹配成功,返回匹配的起始比较下标;否则,匹配失败,返回0;
模式匹配——BF算法
int BF(char S[ ], char T[ ])int BF(char S[ ], char T[ ])
{{
i=1; j=1; i=1; j=1;start=1;
while (i<=S[0]&&j<=T[0])while (i<=S[0]&&j<=T[0])
{{
if (S[i]==T[j]) {if (S[i]==T[j]) { i++; j++;i++; j++;
} }
else {else {
i=i-j+2; j=1;start++; i=start; j=1;
} }
}}
if (j>T[0]) return (i-j+1); if (j>T[0]) return start;
else return 0;else return 0;
}}
模式匹配——BF算法
设串S长度为n,串T长度为m,在匹配成功的情况下,考虑两种极端情况:
⑴好:不成功的匹配都发生在串T的第一个字符。
例如:S=“aaaaaaaaaabcdccccc”
T="bcd "
模式匹配——BF算法
设串S长度为n,串T长度为m,在匹配成功的情况下,考虑两种极端情况:
好情况:不成功的匹配都发生在串T的第1个字符。设匹配成功发生在si处,则在i-1趟不成功的匹配中共比较了i-1次,第i趟成功的匹配共比较了m次,所以总共比较了i-1+m次,所有匹配成功的可能情况共有 n-m+1种( si可能取值:1,2,…,n-m+1 ),则:
n m− +1 (n m+ )
∑ pi´(i− +1 m)= =O n m( + ) i=1 2
模式匹配——BF算法
设串S长度为n,串T长度为m,在匹配成功的情况下,考虑两种极端情况:坏情况:不成功的匹配都发生在串T的 后一个字符。
例如:S=“aaaaaaaaaaabccccc”
T=“aaab”
模式匹配——BF算法
设串S长度为n,串T长度为m,在匹配成功的情况下,考虑两种极端情况:坏情况:不成功的匹配都发生在串T的 后一个字符。
设匹配成功发生在si处,则在i-1趟不成功的匹配中共比较了(i-1)×m次,第i趟成功的匹配共比较了m次,所以总共比较了i×m次,因此
p i( × m) = = O n( × m) i=1
模式匹配——KMP算法
KMP算法是模式匹配算法的一种改进算法,是D.E.Knuth与
J.H.Morris和V.R.Pratt 同时发现的,因此人们称它为克努特-莫里斯-普拉特操作(简称KMP算法)。
为什么BF算法时间性能低?
在每趟匹配不成功时存在大量回溯,没有利用已经部分匹配的结果。
如何在匹配不成功时主串不回溯?
主串不回溯,模式就需要向右滑动一段距离。
如何确定模式的滑动距离?
模式匹配——KMP算法
模式匹配——KMP算法
结论: i可以不回溯,模式向右滑动到的新比较起点k ,并且k 仅与模式串T有关!
需要讨论两个问题:
①如何由当前部分匹配结果确定模式向右滑动的新比较起点k?
②模式应该向右滑多远才是最高效率的? 模式匹配——KMP算法请抓住部分匹配时的特征:
i 设 i=8,j=5时失配,有s4s5s6s7=t1t2t3t4, ①
1 2 3 4 5 6 789
模式滑动到第k个字符:k=
s s s s s s s s s … 1:一般情况
t t t t t t 2:有s7=t1,②,由①和②有t1=t4
1 2 3 4 5 6 3
:有s6s7=t1t2 ,③,由①和③有t1t2=t3t4
j 4:有s5s6s7=t1t2t3 ,④,由①和④有t1t2t3=t2t3t4 结论:
(1) 滑动位置k仅与模式串T有关;
(2) k与j具有函数关系,由当前失配位置j ,可以计算出滑动位置k(即比较的新起点)。
模式匹配——KMP算法请抓住部分匹配时的两个特征:
ii
S=“a b a b c abc a c b a b” S=“a b a b c abc a c b a b”
T=“abc a c” T=“a bc a c”
kjk
(1)设模式滑动到第k个字符,则T1~Tk-1 =Si-(k-1) ~ Si-1
模式匹配——KMP算法请抓住部分匹配时的两个特征:
ii
S=“a b a b c abc a c b a b” S=“a b a b c abc a c b a b”
T=“abc a c” T=“abc ac”
kjkj
(1) 设模式滑动到第k个字符,则T1~Tk-1 =Si-(k-1) ~ Si-1
(2) 则Tj-(k-1) ~Tj-1 =Si-(k-1) ~Si-1
两式联立可得:T1~Tk-1=Tj-(k-1) ~Tj-1
模式匹配——KMP算法
T1…Tk-1=Tj-(k-1) …Tj-1说明了什么?
(1) k 与 j 具有函数关系,由当前失配位置 j ,可以计算出滑动位置 k(即比较的新起点);
(2) 滑动位置k 仅与模式串T有关。
T1…Tk-1=Tj-(k-1) …Tj-1的物理意义是什么?
从第1位往右经过k-1位
从j-1位往左经过k-1位
模式应该向右滑多远才是 高效率的?
k=max { k |1<k<j 且T1…Tk-1=Tj-(k-1) …Tj-1 }
模式匹配——KMP算法
令k = next[ j ],则:
0 当j=1时 //不比较
next[ j ]=max { k | 1<k<j 且T1…Tk-1=Tj-(k-1) …Tj-1 }
1 其他情况
next[j]函数表征着模式T中最大相同首子串和尾子串(真
子串)的长度。
可见,模式中相似部分越多,则next[j]函数越大,它既表示模式 T 字符之间的相关度越高,模式串向右滑动得越远,与主串进行比较的次数越少,时间复杂度就越低。
模式匹配——KMP算法
(2)计算next[j]的方法:
当j=1时,next[j]=0;
//next[j]=0表示根本不进行字符比较。(i++,j=1)
当j>1时,next[j]的值为:模式串的位置从1到j-1构成的串中所出现的首尾相同的子串的最大长度加1。
当无首尾相同的子串时next[j]的值为1。
//next[j]=1表示从模式串头部开始进行字符比较
模式匹配——KMP算法
模式串 T: a b a a b c a c
可能失配位 j: 1 2 3 4 5 6 7 8
新匹配位k=next[j] : 0 1 1 2 2 3 1 2
j=1时, next[ j ]= 0; j=2时, next[ j ]= 1;
j=3时, T1≠T2,因此,k=1; j=4时, T1=T3,因此,k=2; j=5时, T1=T4,因此,k=2;
以此类推。
作业:
- 已知:
S=“a b a b c a b a a b c a a b a a b a b c a a b” T=“a b a a b a b c”
求模式T的next[j] (01122343 ),写出KMP匹配过程。 - 设输入元素为1,2,3,a,b,输入次序为123ab,元素经过栈后到达输出序列,当所有元素均到达输出序列后,有哪些序列可作为高级语言变量名。
字符串
KMP算法用伪代码描述 - 在串S和串T中分别设比较的起始下标i和j;
- 循环直到S中所剩字符长度小于T的长度或T中所有字符均比较完毕
2.1 如果S[i]=T[j],继续比较S和T的下一个字符;否则
2.2 将j向右滑动到next[j]位置,即j=next[j];
2.3 如果j=0,则将i和j分别加1,准备下一趟比较; - 如果T中所有字符均比较完毕,则返回匹配的起始下标;否则返回0;
字符串
求模式串T的next函数值算法
void GetNext(char T[ ], int next[ ])
{
next[1]=0; j=1; k=0;
while (j<T[0]) if ((k==0)| |(T[j]= =T[k])) { j++; k++; next[j]=k;
}
else k=next[k];
}
多维数组
线性表——具有相同类型的数据元素的有限序列。
限制插入、删除位置
栈——仅在表尾进行插入和删除操作的线性表。
队列——在一端进行插入操作,而另一端进行
特殊线性表 删除操作的线性表。
串——零个或多个字符组成的有限序列 。
限制元素类型为字符
线性表——具有相同类型的数据元素的有限序列。
多维数组
线性表——具有相同类型的数据元素的有限序列。
将元素的类型进行扩充
(多维)数组——线性表中的数据元素可以是线性表,但所有元素的类型相同。
数组的定义
数组是由一组类型相同的数据元素构成的有序集合,每个数据元素称为一个数组元素(简称为元素),每个元素受n(n≥1)个线性关系的约束,每个元素在n个线性关系中的序号i1、i2、…、in称为该元素的下标,并称该数组为 n 维数组。
数组的特点
元素本身可以具有某种结构,属于同一数据类型;
数组是一个具有固定格式和数量的数据集合。
数组示例
a11 a12 … a1n
A= a21 a22 … a2n … … … …
am1 am2 … amn
例如,元素a22受两个线性关系的约束,在行上有一个行前驱a21和一个行后继a23,在列上有一个列前驱a12和和一个列后继a32。
数组——线性表的推广
a11 a12 … a1n
a21 … a2n
… … … …
am1 am2 … amn
二维数组是数据元素为线性表的线性表。
数组的基本操作 在数组中插入(或)一个元素有意义吗?
将元素 x 插入
到数组中第1行第2列。 x
a11 a12 … a1n
A= a21 a22 … a2n
… … … …
am1 am2 … amn
删除数组中
第1行第2列元素。
a11 a12 … a1n
A= a21 a22 … a2n
… … … …
am1 am2 … amn
数组的基本操作
⑴存取:给定一组下标,读出对应的数组元素;
⑵修改:给定一组下标,存储或修改与其相对应的数组元素。
存取和修改操作本质上只对应一种操作——寻址 数组应该采用何种方式存储?
数组没有插入和删除操作,所以,不用预留空间,适合采用顺序存储。
数组的存储结构与寻址——一维数组
设一维数组的下标的范围为闭区间[l,h],每个数组元素占用 c 个存储单元,则其任一元素 ai 的存储地址可由下式确定:
Loc(ai)=Loc(al)+(i-l)×c c
Loc(al) Loc(ai) 数组的存储结构与寻址——二维数组
二维数组 内 存
二维结构 一维结构
常用的映射方法有两种:
按行优先:先行后列,先存储行号较小的元素,行号相同者先存储列号较小的元素。
按列优先:先列后行,先存储列号较小的元素,列号相同者先存储行号较小的元素。
按行优先存储的寻址
按行优先存储的寻址
第l1行 第l1+1行
Loc(al1l2) (i -l1)×(h2 -l2+1)+(j -l2)个元素 Loc(aij)
Loc(aij)=Loc(al1l2)+((i-l1)×(h2-l2+1)+(j-l2))×c 按列优先存储的寻址方法与此类似。
数组的存储结构与寻址——多维数组
n(n>2)维数组一般也采用按行优先和按列优先两种存储方法。任一元素存储地址的计算方法
Loc(aijk ) = Loc(a000) +( i×m2×m3 + j×m3 + k )×c
特殊矩阵和稀疏矩阵
特殊矩阵:矩阵中很多值相同的元素并且它们的分布有一定的规律。
稀疏矩阵:矩阵中有很多零元素。
压缩存储的基本思想是:
⑴为多个值相同的元素只分配一个存储空间;
⑵对零元素不分配存储空间。特殊矩阵的压缩存储——对称矩阵
A= 对称矩阵特点:aij=aji
如何压缩存储?
只存储下三角部分的元素。
对称矩阵的压缩存储
0 … j … n-1
每行元素个数第0行 1
aij在一维数组中的序号
… =(1+2+…+i)+j+1
… = i×(i+1)/2+ j+1
第i-1行 i ∵一维数组下标从0开始
∴aij在一维数组中的下标 k= i×(i+1)/2+ j
(a) 下三角矩阵 (b) 存储说明 © 计算方法
对称矩阵的压缩存储
0 1 2 3 4 5 k n(n+1)/2-1
第0行 第1行 第2行 第n-1行
对于下三角中的元素aij(i≥j),在数组SA中的下标 k与i、j的关系为:k=i×(i+1)/2+j 。
上三角中的元素aij(i<j),因为aij=aji,则访问和它对应的元素aji即可,即:k=j×(j+1)/2+i 。
特殊矩阵的压缩存储——三角矩阵
3 c c c c
6 2 c c c
4 8 1 c c
7 4 6 0 c 8 2 9 5 7
(a) 下三角矩阵
如何压缩存储?
3 4 8 1 0 c 2 9 4 6 c c 1 5 7 c c c 0 8 c c c c 7
(b) 上三角矩阵
只存储上三角(或下三角)部分的元素。
下三角矩阵的压缩存储下三角元素存储
a00 数据结构(a01 a02 aC++03 a版)04 a10 a11 a12 a13 a14 a20 a21 a22 a23 a24 a30 a31 a32 a33 a34 a40 a41 a42 a43 a44
对角线上方的常数——只存一个
0 1 2 3 4 5 k n(n+1)/2
第0行 第1行 第2行
矩阵中任一元素aij在数组中的下标k与i、j的对应关系:
i×(i+1)/2+j 当i≥j
k= n×(n+1)/2 当i<j(对角线上方的常数,只存一个)
数据结构(C++版)
上三角矩阵的压缩存储
上三角元素
存储对角线下方的常数——只存一个
a00 a01 a02 a03 a04 a10 a11 a12 a13 a14 a20 a21 a22 a23 a24 a30 a31 a32 a33 a34 a40 a41 a42 a43 a44
上三角矩阵的压缩存储
0 1 … … … … j n-1 每行元素个数
n
aij在一维数组中的序号
n-1
=(n+n-1+n-2+…+n-(i-1))+j-i+1
n-2
= i×(2n-i+1)/2+ j-i+1
…
∵一维数组下标从0开始
n-(i-1)
∴aij在一维数组中的下标 k= i×(2n-i+1)/2+ j-i
(a)上三角矩阵 (b) 存储说明 © 计算方法
a00 数据结构(a01 a02 aC++03 a版)04
上三角矩阵的压缩存储a20(a10) a21aaa2422 23 (a11 a12 a13 a14) a30 a31 a32 a33 a34
上三角元素a40 a41 a42 a43 a44 存储
对角线下方的常数——只存一个矩阵中任一元素aij在数组中的下标k与i、j的对应关系:
i×(2n-i+1)/2+j-i 当i≤j
k=
n×(n+1) /2 当i>j 特殊矩阵的压缩存储——对角矩阵
对角矩阵:所有非零元素都集中在以主对角线为中心的带状区域中,除了主对角线和它的上下方若干条对角线的元素外,所有其他元素都为零。
对角矩阵的压缩存储——压缩到二维数组中
0 a00 a01
a10 a11 a12 a21 a22 a23 a32 a33 a34 a43 a44 0
映射到二维数组B中,t=i
aij映射到bts,映射关系: s=j-i+1 对角矩阵的压缩存储——压缩到一维数组中
a33 a34
a43 a44
a00 a01 0 0 0
A= a10 a11 a12 0 0
0 a21 a22 a23 0
0 0 a32
0 0 0
(a) 三对角矩阵元素aij在一维数组中的序号
=2 + 3(i-1)+( j-i + 2) =2i+ j+1
∵一维数组下标从0开始
∴元素aij在一维数组中的下标
=2i+ j
0 1 2 3 4 5 6 7 8 9 10 11 12
a00 a01 a10 a11 a12 a21 a22 a23 a32 a33 a34 a43 a44
© 压缩到一维数组中
(b) 寻址的计算方法
稀疏矩阵的压缩存储
稀疏矩阵:零元素居多的矩阵,非零元素个数远远小于矩阵元素总数,如:非零元素个数
< 0.05 矩阵元素总数
15 0 0 0 0 0
0 11 0 0 0 0
A=0 0 0 6 0 0
0 0 0 0 0 0
9 0 0 0 0 0
如何只存储非零元素?注意:稀疏矩阵中的非零元素的分布没有规律。稀疏矩阵的压缩存储
将稀疏矩阵中的每个非零元素表示为: (行号,列号,非零元素值)——三元组定义三元组:
template
struct element
{
int row, col; //行号,列号 T item //非零元素值 };
稀疏矩阵的压缩存储
三元组表:将稀疏矩阵的非零元素对应的三元组所构成的集合,按行优先的顺序排列成一个线性表。
15 0 0 0 0 0
0 11 0 0 0 0
A=0 0 0 6 0 0
0 0 0 0 0 0 9 0 0 0 0 0
三元组表=( (0,0,15), (1,1,11), (2,3,6), (4,0,9) )
如何存储三元组表?稀疏矩阵的压缩存储——三元组顺序表采用顺序存储结构存储三元组表
15 0 0 22 0 -15
0 11 3 0 0 0
0 0 0 6 0 0
A=
0 0 0 0 0 0
91 0 0 0 0 0 三元组顺序表是否
需要预留存储空间?
稀疏矩阵的修改操作
三元组顺序表的插入/删除操作
稀疏矩阵的压缩存储——三元组顺序表
采用顺序存储结构存储三元组表 row col item
0 0 0 15 1 0 3 22
15 0 0 22 0 -152 0 5 -15 0 11 3 0 0 03 1 1 11 0 0 0 6 0 04 1 2 3 A=0 0 0 0 0 0 5 2 3 6
91 0 0 0 0 06 4 0 91 空 空 空
MaxTerm-1 闲 闲 闲
是否对应惟一的稀疏矩阵? 5(矩阵的行数)
6(矩阵的列数)
7(非零元个数)
稀疏矩阵的压缩存储——三元组顺序表
存储结构定义:
const int MaxTerm=100; template
struct SparseMatrix
{
T data[MaxTerm]; //存储非零元素
int mu, nu, tu; //行数,列数,非零元个数
};
稀疏矩阵的压缩存储——十字链表
采用链接存储结构存储三元组表,每个非零元素对应的三元组存储为一个链表结点,结构为:
row col item down right
row:存储非零元素的行号 col:存储非零元素的列号 item:存储非零元素的值 right:指针域,指向同一行中的下一个三元组 down:指针域,指向同一列中的下一个三元组稀疏矩阵的压缩存储——十字链表