130 likes | 271 Views
p. 87 第 1 题. (1) 解: 要求 i,j 到 k 的下标变换公式,就是要知道在 k 之前已有几个非零元素,这些非零元素的个数就是 k 的值,一个元素所在行为 i, 所在列为 j, 则在其前面已有的非零元素个数为: (i*3-1)+j-(i+1) 其中 (i*3-1) 是这个元素前面所有行的非零元素个数, j-(i+1) 是它所在列前面的非零元素个数。 化简可得: k=2i+j; // 下标是从 0 开始的。. p. 87 第 1 题. (2) 解: 因为 K 和 i,j 是一一对应的关系,因此这也不难算出:
E N D
p. 87 第1题 (1) 解: 要求i,j 到k 的下标变换公式,就是要知道在k之前已有几个非零元素,这些非零元素的个数就是k的值,一个元素所在行为i,所在列为j,则在其前面已有的非零元素个数为: (i*3-1)+j-(i+1) 其中 (i*3-1)是这个元素前面所有行的非零元素个数,j-(i+1)是它所在列前面的非零元素个数。 化简可得: k=2i+j; // 下标是从0开始的。
p. 87 第1题 (2) 解: 因为K和i,j是一一对应的关系,因此这也不难算出: i=(k+1)/3 //k+1表示当前元素前有几个非零元素,被3整除就得到行号。 j=(k+1)%3+(k+1)/3-1 //k+1除以3的余数就是表示当前行中第几个非零元素。
p. 87 第2题 解: (1) 因含5*6=30个元素,因此A共占30*4=120个字节。 (2) a45的起始地址为: Loc(a45)=Loc(a00)+(i*n+j)*d =1000+(4*6+5)*4 =1116 (3)按行优先顺序排列时, a25=1000+(2*6+5)*4=1068 (4)按列优先顺序排列时:(二维数组可用行列下标互换来计算) a25=1000+(5*5+2)*4=1108
p. 87 第3题 解:对n 阶矩阵,主对角线上元素满足i=j关系;而另一条次主对角线上元素满足满足n-1-i= j关系,在三元组表示的稀疏矩阵中,元素下表符合这二个条件的就是对角线元素。 Int mat_sum( int a[ ][3] ) { int sum1,sum2, t ,m , n ; sum1=0 ; / *稀疏矩阵A主对角线上元素和*/ sum2=0 ; / *稀疏矩阵A次主对角线上元素和*/ n=a[0][0] ; /*矩阵A的 阶数 n*/ m=a[0][2] ; / *稀疏矩阵A非零元素个数*/ for ( t =0 ; t <m ; t++ ) if ( a[t][0] ==a[t][1] ) /*找元素下标满足i=j*/ sum1=sum1+a[t][2] else if ( (n-1-a[t][0]) ==a[t][1] ) /*找元素下标满足n-1-i= j*/ sum1=sum1+a[t][2] ; return (sum1+sum2); }
p. 87 第4题 解: 对于上三角矩阵,以行为主序顺序存储上三角有效元素部分,元素下标从0开始标识,对于第0行,存储n个元素,第1行存储n-1个元素,…,第i行存储(n-i)个元素,经分析a i i 前面有n+(n-1)+(n-2)+…..(n-i)个元素,即有 元素。而元素ai j和元素a i i 间隔(j-i+1) 则a[i , j ]存放在b[k]中,那么k的计算公式为: k= + (j-i+1)
p. 87 第5题 void matadd(a,b,c) int a[ ][3],b[ ][3],c[ ][3]; { int i=1,j=1,k=1,h; while(i<=a[0][2]&&j<=b[0][2]) if(a[i][0]==b[j][0]) //A,B各取一, 行号是否相同 if(a[i][1]<b[j][1]) //假如行号相等,且A列号小于B { for(h=0;h<3;h++) c[k][h]=a[i][h]; k++; i++; }
p. 87 第5题 else if(a[i][1]>b[j][1]) { for(h=0;h<3;h++) c[k][h]=b[j][h]; k++; j++; } else if(a[i][2]+b[j][2]!=0) //A,B阵元素行号,列号相等 { c[k][0]=b[j][0]; c[k][1]=b[j][1]; c[k][2]=a[i][2]+b[j][2]; k++; i++; j++;} else {i++; j++;}
p. 87 第5题 else if(a[i][0]<b[j][0]) //A阵当前行号小于B阵当前行号 { for(h=0;h<3;h++) //将A阵元素直接送C,i+1,j不动 c[k][h]=a[i][h]; k++; i++; } else { for(h=0;h<3;h++) //将B阵元素直接送C,j+1,i不动 c[k][h]=b[j][h]; k++; j++;} //返回while(i<=a[0][2]&&j<=b[0][2]) while(i<=a[0][2]) { for(h=0;h<3;h++) c[k][h]=a[i][h]; k++; i++; }
p. 87 第5题 while(j<=b[0][2]) { for(h=0;h<3;h++) c[k][h]=b[j][h]; k++; j++; } c[0][0]=a[0][0]; c[0][1]=a[0][1]; c[0][2]=k-1; } // 时间复杂度:O(矩阵行数*矩阵列数)
p. 87 第6题 解: 转置矩阵就是将矩阵元素的行号与列号互换,根据已知的三对角矩阵的特点,其转置矩阵对角线元素不变,非零的非对角线元素aij与aji互换位置。又知元素的下标和存放一维数组空间位置的关系:k=2i+j。我们可以设计出这个矩阵的转置算法: #define N 8 //矩阵行、列数 #define L (3*N-2) //压缩矩阵的长度 typedef struct{ int data[L]; }NODE;
p. 87 第6题 void TransMat (NODE *C) //压缩三对角矩阵转置 { int i, j; int t; for(i=0; i<N;i++) for(j=i; j<N; j++) if(i-j<=1&&i-j>=-1) { //将对应于行列号的压缩矩阵内的元素互换 t=C->data[2*i+j]; C->data[2*i+j]=C->data[2*j+i]; C->data[2*j+i]=t; } //endif } //end
p. 87 第7题 #include “stdio.h” struct node{ int row,col,val; struct node *right, *down; } NODE; NODE *mat_transpose(NODE *a) { NODE *b,*p,*q; b=create_null_mat(a->col,a->row); p=a->right; while(p!=a) { q=p->down; while(q!=p) { insert_node(b,q->col, q->row,q->val); q=q->down; } p=p->right; } return(b); }
p. 87 第11题 解:(1) p ; (2) (k,p,h) ; (3)(a,b); (4)((c,d)); (5)(c,d); (6)(b); (7) b; (8)(d)