孤独的猫

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

[程序说明]

设对于一个 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 ); ·

}  

posted on 2011-07-02 20:09  孤独的猫  阅读(728)  评论(2编辑  收藏  举报