数据结构 第三章的扩展 特殊矩阵--压缩存储

一维数组的存放形式:

 

二维数组的存放形式:

行优先原则(C语言数组内存分配)

列优先原则(fortran 语言内存分配)

 

 矩阵可以看做是二维数组,二维数组以某种优先原则的形式存储为一维数组。如果矩阵中有某些相同规律且重复的元素,转为一维数组时,删掉重复元素,从而实现压缩存储。

以下存储都已行优先原则存储。

【对称矩阵】

沿左对角线对称的矩阵。

 

 特点: A[i][j] == A[j][i]

需要一维数组的大小:

行优先存储,按行计算元素个数。

 

1 + 2 + 3 + 4 + 5 = 5 *(1 + 5 ) / 2 = 15

归纳 n*n的对称矩阵需要的一维数组大小:

1 + 2 + 3 + ... + n = n * (1 + n) / 2

 

二维转一维简要代码:

k = 0;

m = n * (1 + n) / 2;

B[m];

for i = 0; i < n; i++

   for j = 0; j <= i; j++

  B[k++] = A[i][j]

 

一维转二维:

 

 设 A[i][j] = = B[k],那么,i行前面的 i-1 行元素,因为从0行开始,第i-1行有 i-1 + 1 个元素列数满足 MAX(col) == row的,即,1 + 2 + ... + i  个元素

所以:   k = 1 + 2 + ... + i-1 + j  = i*(i+1) / 2 + j

一维转二维数组简码:

for i = 0; i < n; i++

   for j = 0; j <= i; j++

        k = i*(i+1) / 2 + j;

  A[i][j] = B[k];

       A[j][i] = B[k];

 

 【三角矩阵】

 

 

上三角矩阵:

i > j , A[i][j] = 常量

else, A[i][j] = 其他值

下三角矩阵:

i < j , A[i][j] = 常量

else, A[i][j] = 其他值

 

以上三角矩阵为例:

归纳 n*n的三角矩阵需要的一维数组大小:

n + n-1 + ...  + 1 = n * (1 + n) / 2 + 1 ,其中1 为存储下三角区常量值。

二维转一维简要代码:

k = 0;

m = n * (1 + n) / 2 + 1;

B[m];

for i = 0; i < n; i++

   for j = 0; j < n-i; j++

  B[k++] = A[i][j]

B[m-1] = c;

一维转二维:

 

 设 A[i][j] = = B[k],那么,i行前面的 i-1 (i > 0)行元素,因为从0行开始,第i-1行有 n-i +1 个元素列数满足 MAX(col) == row的,即,n + n-1 + ... +  n-i +1个元素, 索引为 i行前面有 i行,因为行号从 0 开始。

所以:   k = n + n-1 + ... +  n-i +1 = (2n - i + 1)/  2 *  i + j - i

一维转二维数组简码:

for i = 0; i < n; i++

   for j = 0; j < n- i; j++

        A[i][j] = B[m-1] ;

for i = 0; i < n; i++

   for j = 0; j < n- i; j++

     if i == 0        k = j;

    else              k = (2n - i + 1) /  2 *  i + j - i;

 A[i][j] = B[k];

 

 

【三对角矩阵 又叫 带状矩阵】

 

i - j  >1   || j - i > 1, A[i][j] = 常量

else, A[i][j] = 其他值

 

归纳 n*n的三对角矩阵需要的一维数组大小[大小都为常量]:

2 + 3 + 3+... + 3 +2  +1 = (3-1)+ 3 + 3+... + 3 + (3-1) +1  = 3n -2 + 1 ,其中1 为存储带状以外的常量值。

 

二维转一维简要代码:

k = 0;

m = 3*n -2 + 1;

B[m];

for i = 0; i < n; i++

   for j = 0; j < n; j++

  if   i - j  >1   || j - i > 1   continue;

  B[k++] = A[i][j]

B[m-1] = c;

 

一维转二维:

 

 设 A[i][j] = = B[k],那么,i行前面的 i-1 (i > 0)行元素,因为从0行开始,0行有 2个元素,从 1行开始,有3个元素,前 i- 1 行总共有 3(i-1)+2 , i > 1。第i行, j元素下标为 j-i+1

所以:   k = 3(i-1)+2 +  j-i+1

一维转二维数组简码:

for i = 0; i < n; i++

   for j = 0; j < n- i; j++

        A[i][j] = B[m-1] ;

for i = 0; i < n; i++

   for j = 0; j < n; j++

       if   i - j  >1   || j - i > 1   continue;

       if i == 0        k = j;

      else              k = 3(i-1)+2 +  j-i+1

   A[i][j] = B[k];

补充:

i = (k+1 )/ 3

j = k - 2i

 

【稀疏矩阵】

有效数据比较少的矩阵,如下图:

 

 

 表示方法,十字链表法

struct head {

  type* rownext;

  type  value;

     type* colnext;

}

 为形象表示,分为行头和列头

 后面的稀疏图表示也要用到 十字链表法。

 

 

 

 

 

 

 

 

 

结束。

posted @ 2021-01-26 17:41  雪域蓝心  阅读(385)  评论(0编辑  收藏  举报