数据结构—数组和特殊矩阵 Ⅸ

数据结构-数组和广义表(第六章)的整理笔记,若有错误,欢迎指正。
Link:C语言中的数组
!需要注意的是,本章的数组是作为一种数据结构讨论的,而C/C++中的数组是一种数据类型,前者可以借助后者来存储,像线性表的顺序存储结构(即顺序表)就是借助一维数组这种数据类型来存储的,但二者不能混淆!

数组是具有相同类型的数据元素的有限序列,可以将它看作是线性表的推广。

数组的存储结构

  • 在设计数组的存储结构时,通常将数组的所有元素存储到存储器的一块地址连续的内存单元中,即数组特别适合采用顺序存储结构来存储。

一维数组的存储结构

  • 对于一维数组 ( a 1 , a 2 , . . . , a n ) (a_1,a_2,...,a_n) (a1,a2,...,an),元素顺序存储到一块地址连续的内存单元中。假设第一个元素 a 1 a_1 a1的存储地址用 L O C ( a 1 ) LOC(a_1) LOC(a1)表示,每个元素占用k个存储单元,则任一数组元素 a i a_i ai的存储地址 L O C ( a i ) LOC(a_i) LOC(ai)即可由以下公式求出:
    L O C ( a i ) = L O C ( a 1 ) + ( i − 1 ) × k        ( 2 ≤ i ≤ n ) LOC(a_i)= LOC(a_1)+(i-1)×k\;\;\;(2≤i≤n) LOC(ai)=LOC(a1)+(i1)×k(2in)
  • 该式说明一维数组中任一元素的存储地址可直接计算得到,即一维数组中的任一元素可直接存取,正因为如此,一维数组具有随机存储特性。

二维数组的存储结构

  • 对于一个m行n列的二维数组 A m × n A_{m×n} Am×n
    [ a 1 , 1 a 1 , 1        ⋯        a 1 , n a 2 , 1 a 2 , 2        ⋯        a 2 , n ⋮ ⋮        ⋱        ⋮ a m , 1 a m , 2        ⋯        a m , n ] \begin{bmatrix} a_{1,1} & a_{1,1} \;\;\;\cdots\;\;\;a_{1,n}\\ a_{2,1} & a_{2,2} \;\;\;\cdots\;\;\;a_{2,n}\\ \vdots & \vdots \;\;\;\ddots\;\;\;\vdots\\ a_{m,1} & a_{m,2} \;\;\;\cdots\;\;\;a_{m,n}\\ \end{bmatrix} a1,1a2,1am,1a1,1a1,na2,2a2,nam,2am,n
    A m × n A_{m×n} Am×n简记为A,A是这样的一维数组: A = ( A 1 , A 2 , . . . , A i , . . . , A m ) A=(A_1,A_2,...,A_i,...,A_m) A=(A1,A2,...,Ai,...,Am)
    其中 A i = ( a i , 1 , a i , 2 , . . . , a i , n )        ( 1 ≤ i ≤ m ) A_i=(a_{i,1},a_{i,2},...,a_{i,n})\;\;\;(1≤i≤m) Ai=(ai,1,ai,2,...,ai,n)(1im)
  • 对于二维数组来说,其存储方式主要有两种,即按行优先存放(或者以行序为主序存放)和按列优先存放(或者以列序为主序存放)。

二维数组按行优先存放

  • 即先存储第1行,紧接着存储第2行…依此类推,最后存储第m行。
a 1 , 1 a_{1,1} a1,1 a 1 , 2 a_{1,2} a1,2 a 1 , n a_{1,n} a1,n
a 2 , 1 a_{2,1} a2,1 a 2 , 2 a_{2,2} a2,2 a 2 , n a_{2,n} a2,n
a i , 1 a_{i,1} ai,1 a i , 2 a_{i,2} ai,2 a i , j a_{i,j} ai,j a i , n a_{i,n} ai,n
a m , 1 a_{m,1} am,1 a m , 2 a_{m,2} am,2 a m , n a_{m,n} am,n

二维数组按行优先存放为:

a 1 , 1 a_{1,1} a1,1 a 1 , 2 a_{1,2} a1,2 a 1 , n a_{1,n} a1,n a 2 , 1 a_{2,1} a2,1 a 2 , 2 a_{2,2} a2,2 a 2 , n a_{2,n} a2,n a i , 1 a_{i,1} ai,1 a i , 2 a_{i,2} ai,2 a i , j − 1 a_{i,j-1} ai,j1 a i , j a_{i,j} ai,j a i , n a_{i,n} ai,n a m , 1 a_{m,1} am,1 a m , 2 a_{m,2} am,2 a m , n a_{m,n} am,n
第1行第2行第i行第m行

在这里插入图片描述

  • 假设第一个元素 a 1 , 1 a_{1,1} a1,1的存储地址用 L O C ( a 1 , 1 ) LOC(a_{1,1}) LOC(a1,1)表示,每个元素占用k个存储单元,则该二维数组中的任一元素 a i , j a_{i,j} ai,j的存储地址可由下式确定:
    L O C ( a i , j ) = L O C ( a 1 , 1 ) + [ ( i − 1 ) × n + ( j − 1 ) × k LOC(a_{i,j})=LOC(a_{1,1})+[(i-1)×n+(j-1)×k LOC(ai,j)=LOC(a1,1)+[(i1)×n+(j1)×k
  • 上式推导的思路是,在内存中元素 a i , j a_{i,j} ai,j前面有 i − 1 i-1 i1行,每行n个元素,即已存放了 ( i − 1 ) × n (i-1)×n (i1)×n个元素,占用了 ( i − 1 ) × n × k (i-1)×n×k (i1)×n×k个内存单元;在第i行中元素 a i , j a_{i,j} ai,j前面有 j − 1 j-1 j1个元素,即已存放了 j − 1 j-1 j1个元素,占用了 ( j − 1 ) × k (j-1)×k (j1)×k个内存单元;该数组是从基地址 L O C ( a 1 , 1 ) LOC(a_{1,1}) LOC(a1,1)开始存放的。所以,元素 a i , j a_{i,j} ai,j的内存地址为上述3个部分之和。

以上讨论假设二维数组的行、列下界为1。在更一般的情况下,假设二维数组的行下界是 c 1 c_1 c1,行上界是 d 1 d_1 d1,列下界是 c 2 c_2 c2,列上界是 d 2 d_2 d2,即数组 A [ c 1 . . d 1 , c 2 . . d 2 ] A[c_1..d_1,c_2..d_2] A[c1..d1,c2..d2],则可将上式改写为:

L O C ( a i , j ) = L O C ( a c 1 , c 2 ) + [ ( i − c 1 ) × ( d 2 − c 2 + 1 ) + ( j − c 2 ) ] × k LOC(a_{i,j})=LOC(a_{c_1,c_2})+[(i-c_1)×(d_2-c_2+1)+(j-c_2)]×k LOC(ai,j)=LOC(ac1,c2)+[(ic1)×(d2c2+1)+(jc2)]×k



二维数组按列优先存放

  • 即先存储第1列,紧接着存储第2列…依此类推,最后存储第n列。

二维数组按列优先存放为:

a 1 , 1 a_{1,1} a1,1 a 2 , 1 a_{2,1} a2,1 a m , 1 a_{m,1} am,1 a 1 , 2 a_{1,2} a1,2 a 2 , 2 a_{2,2} a2,2 a m , 2 a_{m,2} am,2 a 1 , j a_{1,j} a1,j a 2 , j a_{2,j} a2,j a i − 1 , j a_{i-1,j} ai1,j a i , j a_{i,j} ai,j a m , j a_{m,j} am,j a 1 , n a_{1,n} a1,n a 2 , n a_{2,n} a2,n a m , n a_{m,n} am,n
第1列第2列第j列第n列

在这里插入图片描述

  • 假设第一个元素 a 1 , 1 a_{1,1} a1,1的存储地址用 L O C ( a 1 , 1 ) LOC(a_{1,1}) LOC(a1,1)表示,每个元素占用k个存储单元,则该二维数组中的任一元素 a i , j a_{i,j} ai,j的存储地址可由下式确定:
    L O C ( a i , j ) = L O C ( a 1 , 1 ) + [ ( j − 1 ) × m + ( i − 1 ) × k LOC(a_{i,j})=LOC(a_{1,1})+[(j-1)×m+(i-1)×k LOC(ai,j)=LOC(a1,1)+[(j1)×m+(i1)×k
  • 上式推导的思路是,在内存中元素 a i , j a_{i,j} ai,j前面有 j − 1 j-1 j1行,每列m个元素,即已存放了 ( j − 1 ) × m (j-1)×m (j1)×m个元素,占用了 ( j − 1 ) × m × k (j-1)×m×k (j1)×m×k个内存单元;在第j列中元素 a i , j a_{i,j} ai,j前面有 i − 1 i-1 i1个元素,即已存放了 i − 1 i-1 i1个元素,占用了 ( i − 1 ) × k (i-1)×k (i1)×k个内存单元;该数组是从基地址 L O C ( a 1 , 1 ) LOC(a_{1,1}) LOC(a1,1)开始存放的。所以,元素 a i , j a_{i,j} ai,j的内存地址为上述3个部分之和。

以上讨论假设二维数组的行、列下界为1。在更一般的情况下,假设二维数组的行下界是 c 1 c_1 c1,行上界是 d 1 d_1 d1,列下界是 c 2 c_2 c2,列上界是 d 2 d_2 d2,即数组 A [ c 1 . . d 1 , c 2 . . d 2 ] A[c_1..d_1,c_2..d_2] A[c1..d1,c2..d2],则可将上式改写为:

L O C ( a i , j ) = L O C ( a c 1 , c 2 ) + [ ( j − c 2 ) × ( d 1 − c 1 + 1 ) + ( i − c 1 ) ] × k LOC(a_{i,j})=LOC(a_{c_1,c_2})+[(j-c_2)×(d_1-c_1+1)+(i-c_1)]×k LOC(ai,j)=LOC(ac1,c2)+[(jc2)×(d1c1+1)+(ic1)]×k

  • 从中可以看出,二维数组无论按行优先存储还是按列优先存放存储,都可以在O(1)的时间内计算出指定下标元素的存储地址,体现出随机存储特性。

特殊矩阵的压缩存储

  • 特殊矩阵是指非零元素或零元素的分布有一定规律的矩阵,为了节省存储空间,特别是在高阶矩阵的情况下,可以利用特殊矩阵的规律对它们进行压缩存储,以提高存储空间效率
  • 特殊矩阵的主要形式有对称矩阵、对角矩阵等。它们都是方阵,即行数和列数相同。

对称矩阵的压缩存储

  • 若一个n阶方阵A[n][n]中的元素满足 a i , j = a j , i , ( 0 ≤ i , j ≤ n − 1 ) a_{i,j}=a_{j,i},(0≤i,j≤n-1) ai,j=aj,i,(0ijn1),则称其为n阶对称矩阵( symmetric matrix)。
    一般情况下,一个n阶方阵的所有元素可以分为3个部分,即主对角部分(含n个元素)、上三角部分和下三角部分,已知一个元素的下标,就可以确定它属于哪个部分。
    在这里插入图片描述

  • 对称矩阵中的元素是按主对角线对称的,即上三角部分和下三角部分中的对应元素相等,因此在存储时可以只存储主对角线加上三角部分的元素,或者主对角线加下三角部分的元素,让对称的两个元素共享一个存储空间。
    在这里插入图片描述

  • a i , j a_{i,j} ai,j是A中主对角线或者下三角部分的元素,有 i ≥ j i≥j ij。在以行序为主序的存储方式下不计行下标为i的行,元素 a i , j a_{i,j} ai,j的前面共存储了i-1行(行下标为1~i-1,行下标为1的行有一个元素,行下标为2的行有两个元素,…,行下标为i-1的行有i-1个元素),则i-1行共有 1 + 2 + … + ( i − 1 ) = [ 1 + ( i − 1 ) ] × ( i − 1 ) 2 1+2+…+(i-1)=\frac{[1+(i-1)]×(i-1)}{2} 1+2++(i1)=2[1+(i1)]×(i1)个元素;在行下标为i的行中,元素 a i , j a_{i,j} ai,j的前面也存储了j-1个元素。所以元素 a i , j a_{i,j} ai,j的前面共存储了 i × ( i − 1 ) 2 + ( j − 1 ) \frac{i×(i-1)}{2}+(j-1) 2i×(i1)+(j1)个元素,而B数组的下标是从0开始的,所以有 k = i × ( i − 1 ) 2 + ( j − 1 ) k=\frac{i×(i-1)}{2}+(j-1) k=2i×(i1)+(j1)

  • a i , j a_{i,j} ai,j是A中上三角部分的元素,有 i < j i<j ij。其值等于 a j , i a_{j,i} aj,i,而元素 a j , i a_{j,i} aj,i属于情况(1),它存放在B中下标为 j × ( j − 1 ) 2 + ( i − 1 ) \frac{j×(j-1)}{2}+(i-1) 2j×(j1)+(i1)的位置,所以此时有k= j × ( j − 1 ) 2 + ( i − 1 ) \frac{j×(j-1)}{2}+(i-1) 2j×(j1)+(i1)

对称矩阵的压缩存储(按行优先存放):

行下标为1的行:1个元素行下标为2的行:2个元素行下标为i-1的行:i-1个元素行下标为i的行: a i , j a_{i,j} ai,j前面有j-1个元素行下标为n的行:n个元素
a 1 , 1 a_{1,1} a1,1 a 2 , 1 a_{2,1} a2,1 a 2 , 2 a_{2,2} a2,2 a i − 1 , 1 a_{i-1,1} ai1,1 a i − 1 , 2 a_{i-1,2} ai1,2 a i − 1 , i − 1 a_{i-1,i-1} ai1,i1 a i , 1 a_{i,1} ai,1 a i , 2 a_{i,2} ai,2 a i , j − 1 a_{i,j-1} ai,j1 a i , j a_{i,j} ai,j a i , i a_{i,i} ai,i a n , 1 a_{n,1} an,1 a n , n a_{n,n} an,n
b 0 b_0 b0 b 1 b_1 b1 b 2 b_2 b2 b k b_k bk b n ( n + 1 ) 2 − 1 b_{\frac{n(n+1)}{2}-1} b2n(n+1)1

将两种情况合起来,得到k与i、j的关系如下:

k = { i × ( i − 1 ) 2 + ( j − 1 )          i ≥ j ( 下 三 角 区 和 主 对 角 线 元 素 ) j × ( j − 1 ) 2 + ( i − 1 )          i < j ( 上 三 角 区 元 素 a i , j = a j , i ) k=\begin{cases} \frac{i×(i-1)}{2}+(j-1)\;\;\;\;i≥j(下三角区和主对角线元素) \\ \frac{j×(j-1)}{2}+(i-1)\;\;\;\;i<j(上三角区元素a_{i,j}=a_{j,i}) \\ \end{cases} k={2i×(i1)+(j1)ij(线)2j×(j1)+(i1)ij(ai,j=aj,i)



  • a i , j a_{i,j} ai,j是A中主对角线或者下三角部分的元素,有 i ≥ j i≥j ij。在以列序为主序的存储方式下不计列下标为j的列,元素 a i , j a_{i,j} ai,j的前面共存储了j-1列(列下标为1~j-1,列下标为1的列有n个元素,列下标为2的列有n-1个元素,…,列下标为j-1的列有n-j+2个元素),则j-1列共有 n + ( n − 1 ) + . . . ( n − j + 2 ) = ( 2 n − j + 2 ) × ( j − 1 ) 2 n+(n-1)+...(n-j+2)=\frac{(2n-j+2)×(j-1)}{2} n+(n1)+...(nj+2)=2(2nj+2)×(j1)个元素;在列下标为j的列中,元素 a i , j a_{i,j} ai,j的前面也存储了i-j个元素。所以元素 a i , j a_{i,j} ai,j的前面共存储了 ( 2 n − j + 2 ) × ( j − 1 ) 2 + ( i − j ) \frac{(2n-j+2)×(j-1)}{2}+(i-j) 2(2nj+2)×(j1)+(ij)个元素,而B数组的下标是从0开始的,所以有 k = ( 2 n − j + 2 ) × ( j − 1 ) 2 + ( i − j ) k=\frac{(2n-j+2)×(j-1)}{2}+(i-j) k=2(2nj+2)×(j1)+(ij)
  • a i , j a_{i,j} ai,j是A中上三角部分的元素,有 i < j i<j ij。其值等于 a j , i a_{j,i} aj,i,而元素 a j , i a_{j,i} aj,i属于情况(1),它存放在B中下标为 ( 2 n − i + 2 ) × ( i − 1 ) 2 + ( j − i ) \frac{(2n-i+2)×(i-1)}{2}+(j-i) 2(2ni+2)×(i1)+(ji)的位置,所以此时有k= ( 2 n − i + 2 ) × ( i − 1 ) 2 + ( j − i ) \frac{(2n-i+2)×(i-1)}{2}+(j-i) 2(2ni+2)×(i1)+(ji)

对称矩阵的压缩存储(按列优先存放):

列下标为1的列:n个元素列下标为2的列:n-2个元素列下标为j-1的列:n-j+2个元素列下标为j的列: a i , j a_{i,j} ai,j前面有i-j+1个元素列下标为n的列:1个元素
a 1 , 1 a_{1,1} a1,1 a 2 , 1 a_{2,1} a2,1 a 3 , 1 a_{3,1} a3,1 a n , 1 a_{n,1} an,1 a 2 , 2 a_{2,2} a2,2 a n , 2 a_{n,2} an,2 a j − 1 , j − 1 a_{j-1,j-1} aj1,j1 a n , j − 1 a_{n,j-1} an,j1 a j , j a_{j,j} aj,j a i − 1 , j a_{i-1,j} ai1,j a i , j a_{i,j} ai,j a n , n a_{n,n} an,n
b 0 b_0 b0 b 1 b_1 b1 b 2 b_2 b2 b k b_k bk b n ( n + 1 ) 2 − 1 b_{\frac{n(n+1)}{2}-1} b2n(n+1)1

将两种情况合起来,得到k与i、j的关系如下:

k = { ( 2 n − j + 2 ) × ( j − 1 ) 2 + ( i − j )          i ≥ j ( 下 三 角 区 和 主 对 角 线 元 素 ) ( 2 n − i + 2 ) × ( i − 1 ) 2 + ( j − i )          i < j ( 上 三 角 区 元 素 a i , j = a j , i ) k=\begin{cases} \frac{(2n-j+2)×(j-1)}{2}+(i-j)\;\;\;\;i≥j(下三角区和主对角线元素) \\ \frac{(2n-i+2)×(i-1)}{2}+(j-i)\;\;\;\;i<j(上三角区元素a_{i,j}=a_{j,i}) \\ \end{cases} k={2(2nj+2)×(j1)+(ij)ij(线)2(2ni+2)×(i1)+(ji)ij(ai,j=aj,i)

  • 显然,一维数组B中存放的元素个数为 1 + 2 + … + n = n ( n + 1 ) 2 1+2+…+n=\frac{n(n+1)}2 1+2++n=2n(n+1)。如果A直接采用个n行n列的二维数组存储,所需要的存储空间为 n 2 n^2 n2个元素,所以这种压缩存储方法几乎节省了一半的存储空间。另外,由于一维数组B具有随机存取特性,所以采用这种压缩存储方法后对称矩阵A仍然具有随机存取特性。
  • 归纳起来,在计算A中元素 a i , j a_{i,j} ai,j在B中存储位置k时,首先求出元素 a i , j a_{i,j} ai,j前面共存放多少个元素(设为m个);再看B中存放元素的下标是从0开始还是从1开始(设B的初始下标为s),则k=m+s。


上、下三角矩阵的压缩存储

  • 所谓上三角矩阵( upper triangular matrix)是指矩阵的下三角部分中的元素均为常数c的n阶方阵。同样,下三角矩阵( lower triangular matrix)是指矩阵的上三角部分中的元素均为常数c的n阶方阵。
    在这里插入图片描述

  • 对于上三角/下三角矩阵,其压缩存储方法是采用以行序为主序/以列序为主序存储其主对角线加上三角部分的元素,另外用一个元素存储常数c,并将压缩结果存放在一维数组B中。显然,B中元素的个数为 n ( n + 1 ) 2 + 1 \frac{n(n+1)}{2}+1 2n(n+1)+1,即用 B [ 0.. n ( n + 1 ) 2 + 1 ] B[0..\frac{n(n+1)}{2}+1] B[0..2n(n+1)+1]存放A中的元素。

在这里插入图片描述

  • a i , j a_{i,j} ai,j是A中主对角线或者下三角部分的元素,有 i ≥ j i≥j ij。在以行序为主序的存储方式下不计行下标为i的行,元素 a i , j a_{i,j} ai,j的前面共存储了i-1行(行下标为1~i-1,行下标为1的行有一个元素,行下标为2的行有两个元素,…,行下标为i-1的行有i-1个元素),则i-1行共有 1 + 2 + … + ( i − 1 ) = [ 1 + ( i − 1 ) ] × ( i − 1 ) 2 1+2+…+(i-1)=\frac{[1+(i-1)]×(i-1)}{2} 1+2++(i1)=2[1+(i1)]×(i1)个元素;在行下标为i的行中,元素 a i , j a_{i,j} ai,j的前面也存储了j-1个元素。所以元素 a i , j a_{i,j} ai,j的前面共存储了 i × ( i − 1 ) 2 + ( j − 1 ) \frac{i×(i-1)}{2}+(j-1) 2i×(i1)+(j1)个元素,而B数组的下标是从0开始的,所以有 k = i × ( i − 1 ) 2 + ( j − 1 ) k=\frac{i×(i-1)}{2}+(j-1) k=2i×(i1)+(j1)
  • a i , j a_{i,j} ai,j是A中上三角部分的元素,有 i < j i<j ij。其值为常数c,用B中最后一个位置(即下标为 n ( n + 1 ) 2 \frac{n(n+1)}{2} 2n(n+1)的元素)存放常数c。

下三角矩阵的压缩存储(按行优先存放):

行下标为1的行:1个元素行下标为2的行:2个元素行下标为i-1的行:i-1个元素行下标为i的行: a i , j a_{i,j} ai,j前面有j-1个元素行下标为n的行:n个元素常数
a 1 , 1 a_{1,1} a1,1 a 2 , 1 a_{2,1} a2,1 a 2 , 2 a_{2,2} a2,2 a i − 1 , 1 a_{i-1,1} ai1,1 a i − 1 , 2 a_{i-1,2} ai1,2 a i − 1 , i − 1 a_{i-1,i-1} ai1,i1 a i , 1 a_{i,1} ai,1 a i , 2 a_{i,2} ai,2 a i , j − 1 a_{i,j-1} ai,j1 a i , j a_{i,j} ai,j a i , i a_{i,i} ai,i a n , 1 a_{n,1} an,1 a n , n a_{n,n} an,nc
b 0 b_0 b0 b 1 b_1 b1 b 2 b_2 b2 b k b_k bk b n ( n + 1 ) 2 − 1 b_{\frac{n(n+1)}{2}-1} b2n(n+1)1 b n ( n + 1 ) 2 b_{\frac{n(n+1)}{2}} b2n(n+1)

将两种情况合起来,得到k与i、j的关系如下:

k = { i × ( i − 1 ) 2 + ( j − 1 )          i ≥ j ( 下 三 角 区 和 主 对 角 线 元 素 ) n ( n + 1 ) 2          i < j ( 上 三 角 区 元 素 ) k=\begin{cases} \frac{i×(i-1)}{2}+(j-1)\;\;\;\;i≥j(下三角区和主对角线元素) \\ \frac{n(n+1)}{2}\;\;\;\;i<j(上三角区元素) \\ \end{cases} k={2i×(i1)+(j1)ij(线)2n(n+1)ij()


  • a i , j a_{i,j} ai,j是A中主对角线或者下三角部分的元素,有 i ≥ j i≥j ij。在以列序为主序的存储方式下不计列下标为j的列,元素 a i , j a_{i,j} ai,j的前面共存储了j-1列(列下标为1~j-1,列下标为1的列有n个元素,列下标为2的列有n-1个元素,…,列下标为j-1的列有n-j+2个元素),则j-1列共有 n + ( n − 1 ) + . . . ( n − j + 2 ) = ( 2 n − j − 2 ) × ( j − 1 ) 2 n+(n-1)+...(n-j+2)=\frac{(2n-j-2)×(j-1)}{2} n+(n1)+...(nj+2)=2(2nj2)×(j1)个元素;在列下标为j的列中,元素 a i , j a_{i,j} ai,j的前面也存储了i-j个元素。所以元素 a i , j a_{i,j} ai,j的前面共存储了 ( 2 n − j − 2 ) × ( j − 1 ) 2 + ( i − j ) \frac{(2n-j-2)×(j-1)}{2}+(i-j) 2(2nj2)×(j1)+(ij)个元素,而B数组的下标是从0开始的,所以有 k = ( 2 n − j − 2 ) × ( j − 1 ) 2 + ( i − j ) k=\frac{(2n-j-2)×(j-1)}{2}+(i-j) k=2(2nj2)×(j1)+(ij)
  • a i , j a_{i,j} ai,j是A中上三角部分的元素,有 i < j i<j ij。其值等于 a j , i a_{j,i} aj,i,而元素 a j , i a_{j,i} aj,i属于情况(1),它存放在B中下标为 ( 2 n − i − 2 ) × ( i − 1 ) 2 + ( j − i ) \frac{(2n-i-2)×(i-1)}{2}+(j-i) 2(2ni2)×(i1)+(ji)的位置,所以此时有k= ( 2 n − i − 2 ) × ( i − 1 ) 2 + ( j − i ) \frac{(2n-i-2)×(i-1)}{2}+(j-i) 2(2ni2)×(i1)+(ji)

下三角矩阵的压缩存储(按列优先存放):

列下标为1的列:n个元素列下标为2的列:n-2个元素列下标为j-1的列:n-j+2个元素列下标为j的列: a i , j a_{i,j} ai,j前面有i-j+1个元素列下标为n的列:1个元素常数
a 1 , 1 a_{1,1} a1,1 a 2 , 1 a_{2,1} a2,1 a 3 , 1 a_{3,1} a3,1 a n , 1 a_{n,1} an,1 a 2 , 2 a_{2,2} a2,2 a n , 2 a_{n,2} an,2 a j − 1 , j − 1 a_{j-1,j-1} aj1,j1 a n , j − 1 a_{n,j-1} an,j1 a j , j a_{j,j} aj,j a i − 1 , j a_{i-1,j} ai1,j a i , j a_{i,j} ai,j a n , n a_{n,n} an,nc
b 0 b_0 b0 b 1 b_1 b1 b 2 b_2 b2 b k b_k bk b n ( n + 1 ) 2 − 1 b_{\frac{n(n+1)}{2}-1} b2n(n+1)1 b n ( n + 1 ) 2 b_{\frac{n(n+1)}{2}} b2n(n+1)

将两种情况合起来,得到k与i、j的关系如下:

k = { ( 2 n − j + 2 ) × ( j − 1 ) 2 + ( i − j )          i ≥ j ( 下 三 角 区 和 主 对 角 线 元 素 ) b n ( n + 1 ) 2          i < j ( 上 三 角 区 元 素 a i , j = a j , i ) k=\begin{cases} \frac{(2n-j+2)×(j-1)}{2}+(i-j)\;\;\;\;i≥j(下三角区和主对角线元素) \\ b_{\frac{n(n+1)}{2}}\;\;\;\;i<j(上三角区元素a_{i,j}=a_{j,i}) \\ \end{cases} k={2(2nj+2)×(j1)+(ij)ij(线)b2n(n+1)ij(ai,j=aj,i)

对角矩阵的压缩存储

  • 若一个n阶方阵A满足其所有非零元素都集中在以主对角线为中心的带状区域中,则称其为n阶对角矩阵(diagonal matrix)。其主对角线上、下方各有b条非零元素构成的次对角线,称b为矩阵半带宽,(2b+1)为矩阵的带宽。对于半带宽为 b ( 0 ≤ b ≤ n ー 1 2 ) b(0≤b≤\frac{nー1}2) b(0b2n1)的对角矩阵,其 ∣ i − j ∣ ≤ b |i-j|≤b ijb的元素 a i , j a_{i,j} ai,j不为零,其余元素为零。
    例:三对角矩阵—其 ∣ i − j ∣ ≤ 1 |i-j|≤1 ij1的元素 a i , j a_{i,j} ai,j不为零,其余元素为零。
    在这里插入图片描述
  • 对于b=1的三对角矩阵,只存储其非零元素,并存储到一维数组B中,将A的非零元素 a i , j a_{i,j} ai,j存储到B的元素 b k b_k bk中。

行优先存储:

  • A中行下标为1的行和行下标为n的行都只有两个非零元素,其余各行有3个非零元素。对于行下标不为1的非零元素 a i , j a_{i,j} ai,j来说,在它前面存储了矩阵的前i-1行元素,这些元素的总数为3(i-1)-1。元素 a i , j a_{i,j} ai,j在行下标为i的行(本行)中分为3种情况:
  1. 若a是本行中的第1个非零元素,则k=3(i-1)-1=3i-4,此时j=i-1,即k
    3i-4=2i-3+(i-1)=2i-3+j。
  2. 若a是本行中的第2个非零元素,则k=3(i-1)-1+1=3i-3,此时j=i,即k
    3i-3=(2i+i)-3=2i+j-3。
  3. 若a是本行中的第3个非零元素,则k=3(i-1)-1+2=3i-2,此时j=i+1,即k
    3i-1=2i-3+(i+1)=2i-3+j。

三对角矩阵的压缩存储(按行优先存放)

行下标为1的行:2个元素行下标为2的行:3个元素行下标为3的行:3个元素行下标为n的行:2个元素
a 1 , 1 a_{1,1} a1,1 a 1 , 2 a_{1,2} a1,2 a 2 , 1 a_{2,1} a2,1 a 2 , 2 a_{2,2} a2,2 a 2 , 3 a_{2,3} a2,3 a 3 , 2 a_{3,2} a3,2 a i , j a_{i,j} ai,j a n , n − 1 a_{n,n-1} an,n1 a n − 1 , n a_{n-1,n} an1,n a n , n a_{n,n} an,n
b 0 b_0 b0 b 1 b_1 b1 b 2 b_2 b2 b k b_k bk b 3 n + 1 b_{3n+1} b3n+1

归纳起来有k=2i+j-3。


列优先存储:

  • A中列下标为1的列和列下标为n的列都只有两个非零元素,其余各列有3个非零元素。对于列下标不为1的非零元素 a i , j a_{i,j} ai,j来说,在它前面存储了矩阵的前j-1列元素,这些元素的总数为3(j-1)-1。元素 a i , j a_{i,j} ai,j在列下标为j的行(本行)中分为3种情况:
  1. 若a是本列中的第1个非零元素,则k=3(j-1)-1=3j-4,此时i=j-1,即k
    3j-4=2j-3+(j-1)=2j-3+i。
  2. 若a是本列中的第2个非零元素,则k=3(j-1)-1+1=3j-3,此时i=j,即k
    3j-3=(2j+j)-3=2j+i-3。
  3. 若a是本列中的第3个非零元素,则k=3(j-1)-1+2=3j-2,此时i=j+1,即k
    3j-1=2j-3+(j+1)=2j-3+i。

三对角矩阵的压缩存储(按列优先存放)

列下标为1的列:2个元素列下标为2的列:3个元素列下标为3的列:3个元素列下标为j的列: a i , j a_{i,j} ai,j前面有i+2j-3个元素列下标为n的列:2个元素
a 1 , 1 a_{1,1} a1,1 a 2 , 1 a_{2,1} a2,1 a 1 , 2 a_{1,2} a1,2 a 2 , 2 a_{2,2} a2,2 a 3 , 2 a_{3,2} a3,2 a 3 , 2 a_{3,2} a3,2 a i , j a_{i,j} ai,j a n − 1 , n a_{n-1,n} an1,n a n , n − 1 a_{n,n-1} an,n1 a n , n a_{n,n} an,n
b 0 b_0 b0 b 1 b_1 b1 b 2 b_2 b2 b k b_k bk b 3 n + 1 b_{3n+1} b3n+1

归纳起来有k=i+2j-3。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值