[程序说明]
设对于一个 n×n 的上三角矩阵 a,为节约存贮,只将它的上三角元素按行主序连续存放在数组 b 中。下面的函数 trans 在不引入工作数组的情况下,实现将 a 改为按列主序连续存放在数组 b 中。
设 n=5,
|
┌1 |
2 |
3 |
4 |
5┐ |
|
│0 |
6 |
7 |
8 |
9│ |
a= |
│0 |
0 |
10 |
11 |
12│ |
|
│0 |
0 |
0 |
13 |
14│ |
|
└0 |
0 |
0 |
0 |
15┘ |
b=(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)
经调用 trans 函数后,b 变为
b=(1,2,6,3,7,10,4,8,11,13,5,9,12,14,15)
函数 tans 对数组元素的存贮位置作调整。调整过程中存在若干个循环传送链:
b(i1)→b(i2)→…→b(ij)→b(i1) 1≤j<n
例如,考察调整后的数组元素 b(2)( 值为 6 ),与该元素相关的位置调整将形成下面的循环传送链:
b(2)→b(3)→b(6)→…→b(12)→b(9)→b(5)→b(2)
关键是确定循环传送链的下标 i1,i2,…,ij ,以及在考察调整后的元素 b(k)( k;3,4,… ) 时能判定 b(k) 是已被传送过的某传送链上的元素。
函数 ctr(k,n) 计算调整后的数组 b 的第 k 个元素 b(k) 在原数组 b 中的位置,该位置作为函数 ctr(k,n) 的返回值。函数 ctr 根据 k 确定它在矩阵中的行号 i 和列号 j ( 注意行号和列号均从 0 算起 ),然后按矩阵存放原则计算出它在 b 中的位置。
[程序]
trans( b,n )
int n,b[]
{
int m,k,r,cc,rr;int w;
m=(n+1)*n/2-4;
k=2
while (m>0)
{
r=ctr(k,n);
if ( r == k )
m--;
else
{ cc=k;rr=r;
while(rr!=k && cc>=k)
{ cc=rr,rr=ctr(cc,n);
}
if (cc>=k)
{ cc=k;rr=r;w=b[k];
while(rr!=k)
{ b[cc]=b[rr];m--;
cc=rr,rr=ctr(cc,n);
}
b[cc]=w;m--;
}
}
k++;
}
}
ctr( k,n )
int k,n;
{
int i,j;
i=k;j=0 ;
while (i>j)
i -= ++j ;
return( i*n+j-i*(i+1)/2 ); ·
}