第五章习题解答
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
//行列值都相等的元素相加
if(A.data[pa].j==B.data[pb].j){
ce=A.data[pa].e+B.data[pb].e; if(ce) //和不为0
{ C.data[pc].i=x;C.data[pc].j=A.data[pa].j; C.data[pc].e=ce; pa++;pb++;pc++; }
练习题
1.假设有二维数组: ElemType A[6][7]
每个元素用相邻的6个字节存放,存储器按字 节编址。已知A的起始地址为1000,计算
(1)数组A的存储量 (2)数组A的最后一个元素A[5][6]的第一个字节的
地址 (3)按行优先存储时,A[2][4]的第一个字节的地
址 (4)按列优先存储时,A[4][6]的第一个字节的地
TSMatrix &C){ //三元组表示的稀疏矩阵加法 C.m=A.m;C.n=A.n; pa=1;pb=1;pc=1; //当前处理的元素在三元组表中的位置 for(x=1;x<=A.m;x++) { //对矩阵的每一行做加法
while(A.data[pa].i<x) pa++; while(B.data[pb].i<x) pb++; while(A.data[pa].i==x&&B.data[pb].i==x) {
i为偶数,k=i+j 合并为一个公式,可有两种形式写法:
k=i-i%2+j k=i+(-1)i /2+j-1/2
3.给定矩阵Am×n,我们将三个顶点分别为 a1n,an1和ann的三角区域的所有元素按行优先 顺序依次存入一维数组B[1..n2 ]中,使得 B[k]=aij,请写出求k的计算公式。
解:根据题设,在aij之前的i-1行中共需存储 (i-1)(1+(i-1))/2个元素,在第i行到j列需存储 的元素共有j-(n-i)个,所以i、j与k之间有如 下关系:
while(m!=i){
temp=A[m];
A[m]=A[i];
A[i]=temp; m=(m+k)%n; } // 循环右移一步 } //for
} //RSh
5.假设稀疏矩阵A和B均以三元组表作为存储结构。试 写出矩阵相加的算法,另设三元组表C存放结果矩阵。
#define MAXSIZE 1000//非零元素个数的最大值 typedef struct{
A.chead[p->j]=cp[p->j]=p->down; else cp[p->j]->down=p->down;
//从列链表中删除 free (p); }//else }//while }//for
} //OLMatrix_Add
A[0]→A[4]→A[8]→A[2]→A[6]→A[0]
但上述过程中可能使有的元素始终没有被 访问过,而是被跳了过去。但若分别以A[0], A[1],···,A[k-1]为起点,再做上述操作, 则有的元素又重复移动了,不合题意。
进一步分析可知,对n和k的最大公约数p, 分别以A[0], A[1],···,A[p-1]为起点执行上述算 法,可以保证每一个元素都被且仅被右移一 次,从而满足题目要求。也就是说,A的所有 元素分别处在p个“循环链”上面。举例如下: 若n=15,k=6,则p=3,分别以A[0],A[1], A[2]为起点的“循环链”为: 第一条链:
C.data[pc].e=A.data[pa].e
pa++;pc++;
}
百度文库
} //while
while(A.data[pa].i==x){ //插入A中剩余的元素(第x行) C.data[pc].i=x; C.data[pc].j=A.data[pa].j; C.data[pc].e=A.data[pa].e pa++;pc++;}
if(!pre) A.rhead[i]=p; else pre->right=p; p->right=pa;pre=p; p->i=i;p->j=pb->j;p->e=pb->e;
//插入行链表中
if(!A.chead[p->j]) { A.chead[p->j]=p; p->down=NULL; }
···
aij ···
a2m-12m-1 a2m-12m a2m 2m-1 a2m 2m
按以下方式存于向量B中
1 2 3 4 5 ··· k ······ 4m-1 4m
a11 a12 a21 a22 a33 ··· aij ··· a2m-1 2m a2m 2m-1 a2m2m
使得B[k]=aij,且k=f1(i)+f2(j)+c。试推 导出函数f1,f2和常数c(要求f1和f2中不含 有常数项) 解:i为奇数,k=i+j-1
else { while(cp[p->j]->down)
cp[p->j]=cp[p->j]->down; p->down=cp[p->j]->down; cp[p->j]->down=p; } cp[p->j]=p; //插入列链表中
} //if
else if(pa->j<pb->j) { pre=pa; pa=pa->right; } //pa右移一步
址
(1) (6×7)×6=252 (2) 1000+41×6-6+1=1246-6+1=1241 (3) 1000+(2×7+4)×6+1=1108+1=1109 (4) 1000+(6×6+4)×6+1=1241
2.设有一个准对角矩阵
a11 a12 a21 a22
a33 a34 a43 a44
A[0]→A[6]→A[12]→A[3]→A[9]→A[0] 第二条链:
A[1]→A[7]→A[13]→A[4]→A[10]→A[1] 第三条链:
A[2]→A[8]→A[14]→A[5]→A[11]→A[2] 恰好使所有元素都右移一次
*4.void RSh(int A[ ], int k,int n){ //把数组A 的元素循环右移k位,只用一个辅助存储空间 for(i=1;i<=k;i++) if(n%i==0&&k%i==0) p=i; //求n和k的最大公约数p for(i=0;i<p;i++){ m=(i+k)%n;
k=(i-1)(1+(i-1))/2+j-(n-i)
=i(i-1)/2+j+i-n
*4.试设计一个算法,将数组A[n]中的元素循环 右移k(<n)位,并要求只用一个元素大小的附 加存储,元素移动或交换次数为O(n)。
分析:
要把A的元素循环右移k位,A[0]移至A[k], A[k]移至A[2k] ,······, 直到最终回到 A[0]。例如,k=4,n=10。
int i,j; //非零元素的行、列下标 ElemType e; //非零元素值 }Triplet; typedef struct{
Triplet data[MAXSIZE+1];// 三元组表,data[0]空
int m,n,t;// 稀疏矩阵的行、列值,非零元素个数 }TSMatrix;
5. void TSMtr_Add(TSMatrix A,TSMatrix B,
6.void OLMatrix_Add(OLMatrix &A,OLMatrix B) {
//把十字链表表示的矩阵B加到A上 for(j=1;j<=A.nu;j++) cp[j]=A.chead[j];
//向量cp存储每一列当前最后一个元素的指针 for(i=1;i<=A.mu;i++){
pa=A.rhead[i];pb=B.rhead[i];pre=NULL; while(pb){ if(pa==NULL||pa->j>pb->j) //新插入一个结点 { p=(OLNode*)malloc(sizeof(OLNode));
} //if
else if(A.data[pa].j>B.data[pb].j)
{
C.data[pc].i=x;
C.data[pc].j=B.data[pb].j;
C.data[pc].e=B.data[pb].e;
pb++;pc++;
}
else
{
C.data[pc].i=x;
C.data[pc].j=A.data[pa].j;
while(B.data[pb].i==x){ //插入B中剩余的元素(第x行) C.data[pc].i=x; C.data[pc].j=B.data[pb].j; C.data[pc].e=B.data[pb].e; pb++;pc++;}
} //for
C.t=pc;
} //TSMtr_Add
6.设稀疏矩阵A和B均以CrossList结构 类型存储,试给出矩阵相加的算法,结 果存于A中。
else if(pa->e+pb->e){ pa->e+=pb->e; pre=pa;pa=pa->right; pb=pb->right;
} //直接相加 else{
if(!pre) A.rhead[i]=pa->right; else pre->right=pa->right; p=pa;pa=pa->right; //从行链表中删除 if(A.chead[p->j]==p)
if(A.data[pa].j==B.data[pb].j){
ce=A.data[pa].e+B.data[pb].e; if(ce) //和不为0
{ C.data[pc].i=x;C.data[pc].j=A.data[pa].j; C.data[pc].e=ce; pa++;pb++;pc++; }
练习题
1.假设有二维数组: ElemType A[6][7]
每个元素用相邻的6个字节存放,存储器按字 节编址。已知A的起始地址为1000,计算
(1)数组A的存储量 (2)数组A的最后一个元素A[5][6]的第一个字节的
地址 (3)按行优先存储时,A[2][4]的第一个字节的地
址 (4)按列优先存储时,A[4][6]的第一个字节的地
TSMatrix &C){ //三元组表示的稀疏矩阵加法 C.m=A.m;C.n=A.n; pa=1;pb=1;pc=1; //当前处理的元素在三元组表中的位置 for(x=1;x<=A.m;x++) { //对矩阵的每一行做加法
while(A.data[pa].i<x) pa++; while(B.data[pb].i<x) pb++; while(A.data[pa].i==x&&B.data[pb].i==x) {
i为偶数,k=i+j 合并为一个公式,可有两种形式写法:
k=i-i%2+j k=i+(-1)i /2+j-1/2
3.给定矩阵Am×n,我们将三个顶点分别为 a1n,an1和ann的三角区域的所有元素按行优先 顺序依次存入一维数组B[1..n2 ]中,使得 B[k]=aij,请写出求k的计算公式。
解:根据题设,在aij之前的i-1行中共需存储 (i-1)(1+(i-1))/2个元素,在第i行到j列需存储 的元素共有j-(n-i)个,所以i、j与k之间有如 下关系:
while(m!=i){
temp=A[m];
A[m]=A[i];
A[i]=temp; m=(m+k)%n; } // 循环右移一步 } //for
} //RSh
5.假设稀疏矩阵A和B均以三元组表作为存储结构。试 写出矩阵相加的算法,另设三元组表C存放结果矩阵。
#define MAXSIZE 1000//非零元素个数的最大值 typedef struct{
A.chead[p->j]=cp[p->j]=p->down; else cp[p->j]->down=p->down;
//从列链表中删除 free (p); }//else }//while }//for
} //OLMatrix_Add
A[0]→A[4]→A[8]→A[2]→A[6]→A[0]
但上述过程中可能使有的元素始终没有被 访问过,而是被跳了过去。但若分别以A[0], A[1],···,A[k-1]为起点,再做上述操作, 则有的元素又重复移动了,不合题意。
进一步分析可知,对n和k的最大公约数p, 分别以A[0], A[1],···,A[p-1]为起点执行上述算 法,可以保证每一个元素都被且仅被右移一 次,从而满足题目要求。也就是说,A的所有 元素分别处在p个“循环链”上面。举例如下: 若n=15,k=6,则p=3,分别以A[0],A[1], A[2]为起点的“循环链”为: 第一条链:
C.data[pc].e=A.data[pa].e
pa++;pc++;
}
百度文库
} //while
while(A.data[pa].i==x){ //插入A中剩余的元素(第x行) C.data[pc].i=x; C.data[pc].j=A.data[pa].j; C.data[pc].e=A.data[pa].e pa++;pc++;}
if(!pre) A.rhead[i]=p; else pre->right=p; p->right=pa;pre=p; p->i=i;p->j=pb->j;p->e=pb->e;
//插入行链表中
if(!A.chead[p->j]) { A.chead[p->j]=p; p->down=NULL; }
···
aij ···
a2m-12m-1 a2m-12m a2m 2m-1 a2m 2m
按以下方式存于向量B中
1 2 3 4 5 ··· k ······ 4m-1 4m
a11 a12 a21 a22 a33 ··· aij ··· a2m-1 2m a2m 2m-1 a2m2m
使得B[k]=aij,且k=f1(i)+f2(j)+c。试推 导出函数f1,f2和常数c(要求f1和f2中不含 有常数项) 解:i为奇数,k=i+j-1
else { while(cp[p->j]->down)
cp[p->j]=cp[p->j]->down; p->down=cp[p->j]->down; cp[p->j]->down=p; } cp[p->j]=p; //插入列链表中
} //if
else if(pa->j<pb->j) { pre=pa; pa=pa->right; } //pa右移一步
址
(1) (6×7)×6=252 (2) 1000+41×6-6+1=1246-6+1=1241 (3) 1000+(2×7+4)×6+1=1108+1=1109 (4) 1000+(6×6+4)×6+1=1241
2.设有一个准对角矩阵
a11 a12 a21 a22
a33 a34 a43 a44
A[0]→A[6]→A[12]→A[3]→A[9]→A[0] 第二条链:
A[1]→A[7]→A[13]→A[4]→A[10]→A[1] 第三条链:
A[2]→A[8]→A[14]→A[5]→A[11]→A[2] 恰好使所有元素都右移一次
*4.void RSh(int A[ ], int k,int n){ //把数组A 的元素循环右移k位,只用一个辅助存储空间 for(i=1;i<=k;i++) if(n%i==0&&k%i==0) p=i; //求n和k的最大公约数p for(i=0;i<p;i++){ m=(i+k)%n;
k=(i-1)(1+(i-1))/2+j-(n-i)
=i(i-1)/2+j+i-n
*4.试设计一个算法,将数组A[n]中的元素循环 右移k(<n)位,并要求只用一个元素大小的附 加存储,元素移动或交换次数为O(n)。
分析:
要把A的元素循环右移k位,A[0]移至A[k], A[k]移至A[2k] ,······, 直到最终回到 A[0]。例如,k=4,n=10。
int i,j; //非零元素的行、列下标 ElemType e; //非零元素值 }Triplet; typedef struct{
Triplet data[MAXSIZE+1];// 三元组表,data[0]空
int m,n,t;// 稀疏矩阵的行、列值,非零元素个数 }TSMatrix;
5. void TSMtr_Add(TSMatrix A,TSMatrix B,
6.void OLMatrix_Add(OLMatrix &A,OLMatrix B) {
//把十字链表表示的矩阵B加到A上 for(j=1;j<=A.nu;j++) cp[j]=A.chead[j];
//向量cp存储每一列当前最后一个元素的指针 for(i=1;i<=A.mu;i++){
pa=A.rhead[i];pb=B.rhead[i];pre=NULL; while(pb){ if(pa==NULL||pa->j>pb->j) //新插入一个结点 { p=(OLNode*)malloc(sizeof(OLNode));
} //if
else if(A.data[pa].j>B.data[pb].j)
{
C.data[pc].i=x;
C.data[pc].j=B.data[pb].j;
C.data[pc].e=B.data[pb].e;
pb++;pc++;
}
else
{
C.data[pc].i=x;
C.data[pc].j=A.data[pa].j;
while(B.data[pb].i==x){ //插入B中剩余的元素(第x行) C.data[pc].i=x; C.data[pc].j=B.data[pb].j; C.data[pc].e=B.data[pb].e; pb++;pc++;}
} //for
C.t=pc;
} //TSMtr_Add
6.设稀疏矩阵A和B均以CrossList结构 类型存储,试给出矩阵相加的算法,结 果存于A中。
else if(pa->e+pb->e){ pa->e+=pb->e; pre=pa;pa=pa->right; pb=pb->right;
} //直接相加 else{
if(!pre) A.rhead[i]=pa->right; else pre->right=pa->right; p=pa;pa=pa->right; //从行链表中删除 if(A.chead[p->j]==p)