第四章数据结构——数组
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
3 0 0 0 7
0 0 1 0 0
A
1
2
0
0
0
0 0 0 0 0
0 0 0 2 0
13 3 -1 ^ 1 -1
5 7^ 2 -2 ^
^ 4 2^
需存储单元个数为3t+m
十字链表
设行指针数组和列指针数组,分别指向每行、
列第一个非零元
3 0 0
结点定义
row col val
tpedef struct node
00 0 18 24 0 00 00 00 00
v
07 6 8
1 1 3 -3
2 1 6 15
3 2 1 12 2 5 18
43 19 5 3 4 24 6 4 6 -7
7 6 3 14
15
0
0
7
0
0
0 7 6
mb
解决思路:只要做到 将矩阵行、列维数互换 将每个三元组中的i和j相互调换 重排三元组次序,使mb中元素以N的行(M的列)为主序
k k
3 2 1 12 2 5 18
k 43 19
5 3 4 24 6 4 6 -7
7 6 3 14
8 mb
方法二:快速转置 即按ma中三元组次序转置,转置结果放入b中恰当位置 此法关键是要预先确定M中每一列第一个非零元在mb中位置, 为确定这些位置,转置前应先求得M的每一列中非零元个数
实现:设两个数组 num[col]:表示矩阵M中第col列中非零元个数 p[col]:指示M中第col列第一个非零元在mb中位置 显然有: p[1]=1;
第一个结点,令rh[r-1]=s; s->right=p; e、若c<p->col且q!=NULL,则在p之前插入s,
即 s->right=p; q->right=s;
算法分析: T(n)=o(ts) 其中:t——非零元个数
s= max(m,n) Ch4_3.c
m=4,n=3 1,1,3 2,2,5 2,3,4 4,1,8 2,1,7
0 0 24 0 0 0 0
4 -7 8
0 18 0 0 0 0 0
15 0 0 7 0 0 0 67
ma
伪地址表示法
伪地址:本元素在矩阵中(包括零元素再内) 按行优先顺序的相对位置
伪地址
0 12 9 0 0 0 0
0
00
0 0 0 0
M 3 0 0 0 0 14 0
0 0 24 0 0 0 0
NRA 06
jv 7 80
非零元值
11
23 33 45 56 67
二元组表需存储单元 个数为2(t+1)+m+1
2 12 1 3 92
矩阵列数和 非零元个数
1 -3 3
6 14 4
0 12 9 0 0 0 0
3 24 5
0
0
0
0 0 0 0
2 18 6 M 3 0 0 0 0 14 0
1 15 7
0 18 0 0 0 0 0
15 0 0 7 0 0 0 67
addr v
06 7
1 2 12
23 9 3 15 -3
20 14 4
24 24 5 30 18 6 36 15 7 39 -7
8 ma
非零元值 矩阵行列维数
伪地址表示法需存储单元个数 为2(t+1)
求转置矩阵 问题描述:已知一个稀疏矩阵的三元组表,求该矩
Loc(i,j)=Loc(0,0)+(i*n+j)*s
0<i≤m-1, 0<j≤n-1
§定义一A[2][3]数组,对应的矩阵如下:
A
a00 a10
a01 a11
a02 a12
数组元素A[1][2],其下标i=1,j=2,故它前 面已经有i=1行,每行有3个元素,另外本行 有j=2个元素,所以在元素A[1][2]之前,本 数组已有5个元素。
Loc(aij)=Loc(a11)+[(
i(i-1) 2
+(j-1)]*l
对角矩阵
a11 a12 0 …………… . 0 a21 a22 a23 0 …………… 0 0 a32 a33 a34 0 ……… 0
……………………………
0 0 … an-1,n-2 an-1,n-1 an-1,n
0 0 … …an,n-1
p[col]=p[col-1]+num[col-1]; (2col ma[0].j)
0 12 9 0 0 0 0
0
0
0
0 0 0 0
M 3 0 0 0 0 14 0
0 0 24 0 0 0 0
0 18 0 0 0 0 0
15 0 0 7 0 0 0 67
col
12 3 4 5 67
num[col] 2 2 2 1 0 1 0
1 13
^^
2 17
^^
4 18 ^^
Ch4_3.c
2 25
^^
2 34
^
^
3.3 广义表
4.3.1基本概念 广义表是第二章提到的线性表的推广。线性表中的元素 仅限于原子项,即不可以再分,而广义表中的元素既可 以是原子项,也可以是子表(另一个线性表)。
方法一:按M的列序转置 即按mb中三元组次序依次在ma中找到相应的三元组进行转置。 为找到M中每一列所有非零元素,需对其三元组表ma从第一行 起扫描一遍。由于ma中以M行序为主序,所以由此得到的恰是mb 中应有的顺序
算法描述:
算法分析:T(n)=O(M的列数n非零元个数t) 若 t 与mn同数量级,则T(n)O(mn2)
❖稀疏矩阵的压缩存储方法
0 12 9 0 0 0 0
0 0 0 0 0 0 0
顺序存储结构
M 3 0 0 0 0 14 0
三元组表 #define M 20
0 0 24 0 0 0 0
typedef struct node 0 18 0 0 0 0 0
行列下标
非零元值 { int i,j;
15 0 0 7 0 0 0 67
ij v
int v; }JD;
06 7 8
JD ma[M];
1 1 2 12
21 3 9
33 3
44
1 -3 6 14 3 24
5 5 2 18 6 6 1 15
7 6 4 -7
8
ma
ma[0].i,ma[0].j,ma[0].v分别存放 矩阵行列维数和非零元个数
0 12 9 0 0 0 0
0 0 0 0 0 0 0
M
3
0
0
0 0 14 0
0 0 24 0 0 0 0
0 18 0 0 0 0 0
15 0 0 7 0 0 0 67
M由{(1,2,12), (1,3,9), (3,1,-3), (3,6,14), (4,3,24), (5,2,18), (6,1,15), (6,4,-7) } 和矩阵维数(6,7)唯一确定
mm**nn--11 amn
1. 一维数组寻址公式
§对于一维数组,若其下标的下界为LB,上 界为UB,第一元素(其下标为LB)的地址 为Loc(LB),下标为i的数组元素A[i]的地址为 Loc(i),则计算Loc(i)的寻址公式为:
Loc(i)=Loc(LB)+(i-LB)*s §在C语言中,数组下标的下界为0,则数组
357
ij v 07 6 8
p 1 1 2 12
p21 3 9
p 3 3 1 -3
p 4 3 6 14
p54 p65
3 24 2 18
p 7 6 1 15
p 8 6 4 -7 ma
1 1 3 -3
2 1 6 15 3 2 1 12
4 2 5 18 53 1 9 6 3 4 24 7 4 6 -7 8 6 3 14
0 0 24 0 0 0 0
0 18 0 0 0 0 0
15 0 0 7 0 0 0 67
ij v
06 7 8
1 1 2 12 ma 2 1 3 9
3 3 1 -3
4 3 6 14 5 4 3 24
?
6 5 2 18
7 6 1 15
8 6 4 -7
0
12
9
N 0
0
0
0
0 3 00 00 00 00 0 14 00 ij
mb
链式存储结构
带行指针向量的单链表表示
每行的非零元用一个单链表存放
设置一个行指针数组,指向本行第一个非零元结点; 若本行无非零元,则指针为空
typedef表头str结uct点no与de单链表结点类型定义
{ int col; int val; struct node *link;
}JD; typedef struct node *TD;
ann.
按行序为主序:
a11 a12 a21 a22 a23 …... …... ann-1 ann
k=0 1 2 3 4
n(n-1)/2 n(n+1)/2-1
Loc(aij)=Loc(a11)+2(i-1)+(j-1)
稀疏矩阵
❖定义:非零元较零元少,且分布没有一定规律的矩阵
❖压缩存储原则:只存矩阵的行列维数和每个非零元的 行列下标及其值
第三章 数组
数组可以看成是一种特殊的线性表,即线性表中数 据元素本身也是一个线性表
§3.1 数组的定义和特点
)
)
)
)
)
定义
(a11 a12 ... ... a1n )
Amn
(a21
a22
... ... a2n )
( ... ... ... ... ... )
(am1 am2 ... ... amn)
阵转置矩阵的三元组表 问题分析 一般矩阵转置算法:
for(col=0;col<n;col++) for(row=0;row<m;row++) n[col][row]=m[row][col];
T(n)=O(mn)
0 12 9 0 0 0 0
0 0 0 0 0 0 0
M 3 0 0 0 0 14 0
(
(
(
(
(
数组特点
❖数组结构固定
❖数据元素同构
数组运算
❖给定一组下标,存取相应的数据元素
❖给定一组下标,修改数据元素的值
§3.2 数组的顺序存储结构
次序约定
❖以行序按为行主列序为主序存放 ❖以列序为主序
0
a11
11
a2112
…….
mn--11
am1n1
aa1111 aa1122 ………….... aa11nn aa2211 aa2222 ………….... aa22nn
Ch4_1.c
ij v
06 7 8
p 1 1 2 12 p
p 21 3 9 p
p 3 3 1 -3
p
p
3 6 14 p
p 4 4 3 24 p
p 5 5 2 18 p
p 6 6 1 15 p
p 7 6 4 -7 p 8 ma
col=1
来自百度文库
col=2
ij v
07 6 8
k 1 1 3 -3
k 2 1 6 15
§3.3 矩阵的压缩存储
三角矩阵 a11 0 0 …….. 0 a21 a22 0 …….. 0
…………………. 0 an1 an2 an3…….. ann
按行序为主序:
a11 a21 a22 a31 a32 …... an1 …... ann
k=0 1 2 3 4
n(n-1)/2 n(n+1)/2-1
三元组表所需存储单元个数为3(t+1) 其中t为非零元个数
带辅助行向量的二元组表
增加一个辅助数组NRA[m+1],其物理意义是第i行第一个非零元
在二元组表中的起始地址(m为行数)
显然有: NRA[1]=1
NRA[i]=NRA[i-1]+第i-1行非零元个数(i2)
列下标和
NRA[0]不用或 存矩阵行数
down right
{ int row,col,val;
struct node *down, *right;
A
0
0
5 0
4
0
8 0 0 4 3
}JD;
1 13
^
2 25
2 34
^
^
^
^
4 18
^^
从键盘接收信息建立十字链表算法
令q=NULL,p=rh[r-1], (1)寻找插入位置:当p!=NULL且c>p->col时,p和q右移 (2)插入: a、若p==NULL且q==NULL,即本行空,则rh[r-1]==s; b、若p==NULL,q!=NULL,即走到行末,则q->right=s c、若c==p->col,则修改p->val d、若c<p->col且q==NULL,则在p之前插入s,即s是行链表中
cpot[col] 1 3 5 7 8 8 9
算法描述: 算法分析:T(n)=O(M的列数n+非零元个数t)
若 t 与mn同数量级,则T(n)=O(mn)
Ch4_2.c
col
12 3 4 5 67
num[col] 2 2 2 1 0 1 0
p[col] 1 3 5 7 8 8 9
246
9
ij v 06 7 8
……………………………………..
nm
a1221
a22
……..
am2n2 ……….
aamm11 aamm22 ………….... aammnn
a1mn1
LLoocc((aiaj)ij=)=LLoco(ca(a111)1+)+[([j(-i1-)1m)n++((ij--11))]]**l l
a2mn2 ……..
中任意一元素A[i]的寻址公式为:
Loc(i)=Loc(0)+i*s 0≤i≤n-1
2. 二维数组寻址公式
§在C语言中,采用矩阵元素以行为主存储,即 同一行的元素连续存放,存储完一行再存储 下一行。
§设二维数组A[m][n],m、n分别表示数组的行 和列,用Loc(i,j)表示数组元素A[i][j]的地址, 每个单元占用s个存储单元,则寻址公式为: