数据结构与算法学习(4)——数组

        有一定c++基础的对数组一定很熟悉,但通常接触到的仅仅是一维数组,所以~这篇文章的开始先介绍二维数组!

A_{m\times n}=\begin{bmatrix} a_{00} & a_{01} & a_{02} & ... & a_{0,n-1}\\ a_{10} & a_{11} & a_{12} & ... & a_{1,n-1}\\ ... & ... & ... & ... & ...\\ a_{m-1,0} & a_{m-1,1} & a_{m-1,2} & ... & a_{m-1,n-1} \end{bmatrix}

对于这样的二维数组,可以看作是两种不同的线性表:

\left ( A_{0},A_{1},...,A_{m-1} \right ) or (A_{0}^{'},A_{1}^{'},...,A_{n-1}^{'})

即按行优先存储和按列优先存储两种方式(存储顺序就不用多说了吧)
所以上述A种任意元素的存储位置的公式即为:LOC(a_{i,j})=\left\{\begin{matrix} LOC(a_{00})+(i\times n +j)\\ LOC(a_{00})+(j\times m +i) \end{matrix}\right.

下面给出二维数组的定义以及删除方式:

int row,col;
row = 10;                                   //行数
col = 5;                                    //列数

//初始化二维数组
int **array = new int*[row];                //先申请int* 型数组的的空间
for(int i = 0;i < row;i++)
{
    array[i] = new int[col];                //再给int* 类型的指针分别分配空间
}

//释放二维数组
for(int i = 0;i < row;i++)
{
    delete[] array[i];                      //先释放数组的数组
}
delete[] array;                             //再释放单个数组
return 0;

那么问题来了,多维数组的存储地址的公式是啥咧?

LOC(A\left [ j_{1} \right ]\left [ j_{2} \right ]......\left [ j_{n} \right ])=first address+\sum_{i=1}^{n}c_{i}j_{i}

其中 c_{n}=L,c_{i-1}=b_{i}\times c_{i},1< i\leq n

原理和二维数组一样,我就不多解释啦(懒)

接下来,到了特殊矩阵的压缩存储环节(好突然),就是矩阵如何用数组的方式进行存储。

(前两个看完矩阵名字却不清楚意思的可以补线代去了)

1.对称矩阵:只考虑对角线以上或以下的部分

下给出考虑对角线以下部分的存储地址公式:

LOC(a_{ij})=LOC(a_{00})+(i\times (i+1)/2 +j)\: \: \: i\geq j

LOC(a_{ij})=LOC(a_{00})+(j\times (j+1)/2 +i)\: \: \: i < j

2.下三角矩阵/上三角矩阵:一个道理

3.带状矩阵:对于n*n阶方阵,非零元素集中在以主对角线为中心的带状区域的矩阵

数学解释:\left | i-j \right |> b,a_{i,j}=0(主对角线以上和下各b条对角线)

进行压缩存储时,只存储带状(部分)内部的元素。

即首行和末行是1+b,其余每行1+2b个元素(如果不够补足),共(n-1)*(1+2b)+1个元素

地址公式:LOC(a_{ij})=LOC(a_{00})+(i\times (1+2b)+j-i)\times L

L前面的系数:(i-1)(2b+1)+(b+1)+(j-i+b)

前两项是0到i-1行的元素数,最后一项是离对角线距离(j-i)加上对角线条数

4.稀疏矩阵

仅用三元组表示(行数,列数,元素值)

附赠代码:

typedef struct
{
    int i,j;        //非零元素的行下标和列下标
    ElemType e;
}Triple;

typedef union
{
    Triple data[MaxSize+1];    //data[0]未用
    struct
    {
        int mu,nu,tu;          //矩阵的行数、列数和非零个数
    };
} TSMatrix;

//联合体中的数据项相对于基地址偏移量都为0,因此相当于data[0]被mu,nu,tu使用了
void CompresSMatrix(matrix A, TSMatrix &M)
{
    int i,j,k = 1;
    for(i = 0;i < A.m;i++)
    {
        for(j = 0;j < A.n;j++)
        {
            if(A.data[i][j] != 0)
            {
                M.data[k].i = i;
                M.data[k].j = j;
                M.data[k].e = A.data[i][j];
                k++;
            }
        }
    }
    M.mu = A.m;
    M.nu = A.n;
    M.tu = k-1;
}

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zedkyx

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值