C++数据结构——数组与广义表

C++数据结构——数组与广义表

参考博客:

(1)理论:https://www.cnblogs.com/KennyRom/p/5971853.html

(2)理论:https://www.cnblogs.com/zyrblog/p/6870097.html

(3)题型:https://www.cnblogs.com/xingyunblog/p/4229812.html

(4)数据结构小结(五)数组与广义表


一、数组

1、数组的定义、特点、操作

    (1) 数组的定义:

            1)一个 N 维数组是受 N 组线性关系约束的线性表。详细定义见数组定义

            2)一维数组是定长线性表; 二维数组是一个定长线性表,它的每个元素是一个一维数组;n维数组是线性表,它的每个元素是n-1维数组。

    (2) 数组的特点:元素数目固定且下标有界。

    (3) 数组的操作:按照下标进行读写。

2、数组的顺序表示与实现

       由于数组一般不作插入与删除操作,一旦建立了数组,结构中的数据元素个数和元素之间的关系就不再发生变动,因此,采用顺序存储结构表示数组是自然的事。计算机的内存结构是一维的,因此用一维内存来表示多维数组,就必须按某种次序将数组元素排成一列序列,然后将这个线性序列存放在储存器中。

       通常有两种顺序存储方式:

      (1)行优先顺序——将数组元素按行排列

               在PASCAL、C语言中,数组就是按行优先顺序储存。(C/C++,Python,Java)

      (2)列优先顺序——将数组按列向量排列。

               在FORTRAN语言中,数组就是按列优先顺序储存的。(FORTRAN,Matlab

3、矩阵的压缩存储

(1)定义

         为节省储存空间,矩阵进行压缩存储:即为多个相同的非零的元素值分配一个储存空间;对0元素不分配空间。

2)特殊矩阵

       对称矩阵,三角矩阵等特殊矩阵的存储方法:非零元素的分布都有一个明显的规律,从而都可将其压缩存储到一维数组中,并找到每个非零元在一维数组中的对应关系

(3)稀疏矩阵

       1)定义

        假设在mxn的矩阵中,有t个元素不为0,令delta=t/(mxn),称delta为矩阵的稀疏因子,通常认为delta <= 0.05 时将矩阵称为稀疏矩阵。 

       2)如何进行稀疏矩阵的压缩存取呢?

        A、三元组顺序表(参考博客:https://www.cnblogs.com/KennyRom/p/5971853.html

         用三项内容表示稀疏矩阵中的每个非零元素,进行形式为:(i,j,value),其中i表示行序号,j表示列序 号,value表示非零元素的值。

//稀疏矩阵,非零元素比较少
const int max=1000;
 
template<typename Object>
typedef struct
{
    int i, j;
    Object e;
}Triple;
 
template<typename Object>
typedef struct
{
    Triple<Object> data[max];
    int mu, nu, tu;
}TSMatrix;
       稀疏矩阵的转置算法:转置前矩阵为M,转置后为T,M的列为T的行,因此,要按M.data的列序转置所得到的转置矩阵T的三元组表必定按行优先存放。其转置算法时间复杂度为O(n*t),代码为:
template<typename Object>
void trans( TSMattrix<Object>M, TSMatrix<Object>T)
{
    T,mu=M.nu;
    T.nu=M.mu;
    T.tu=M.tu;
 
   if(T.tu)
   {
       int q=0;
       for(int col=0; col< M.nu;col++)
           for(int p=0; p<M.tu; p++)
              {
                  if(M.data[p].j==col)
                    {
                         T.data[q].i=M.data[p].j;
             T.data[q].j=M.data[p].i;
             T.data[q].e=M.data[p].e;
             q++;
                    }
              }
    }
}
快速转置算法:

       一遍扫描先确定三元组的位置关系,二次扫描由位置关系装入三元组。为了预先确定矩阵M中的每一列的第一个非零元素在数组B中应有的位置,需要闲球的矩阵M中的每一列中非零元素的个数。为此,需要设计两个一位数组num[0...n-1]和cpot[1..n-1],num[0...n-1]:统计M中每一列非零元素的个数。cpot[0...n-1]:由递推关系得出M中的每列第一个非零元素在B中的位置,cpot[col]=cpot[col-1]+num[col-1]。算法时间复杂度为O(n+t),代码如下:

template<typename Object>
void fasttranstri( TSMatrix<Object> M, TSMatrix<Object>T)
{
    int q;
    int *num=new int[M.nu];
    int *copt=new int[M.nu];
    T.mu=M.nu;
    T.nu=M.mu;
    T.tu=M.tu;
 
    if(M.tu)
    {
        for(int col=0; col<M.nu ;col++)
            num[col]=0;
 
   
        //统计每列非零元素个数
        for(int k=0; col<M.tu; k++)
            ++num[m.data[k].j];
 
        //每列第一个非零元素在T中位置
        copt[0]=0;
        for(int col=1; col <M.nu;col++)
             copt[col]=copt[col-1]+num[col-1];
 
        for(int p=0; p<M.tu; p++)
       {
              int col=M.data[p].j;
          q=cpot[col];
          T.data[q].i=M.data[p].j;
          T.data[q].j=M.data[p].i;
          T.data[q].e=M.data[p].e;
          ++copt[col];
       }
    }
    delete[] num;
    delete[] cpot;
}
       B、行逻辑链接的顺序表

       将快速转置矩阵的算法中创建的指示“行”信息的辅助数组cpot固定在稀疏矩阵的存储结构中,称这种“带行链接信息”的三元组表为行逻辑链接的顺序表。

       C、十字链表

       当矩阵的非零元个数和位置在操作过程中变化较大时,就不宜采用顺序存储结构来表示三元组的线性表了。

    3)稀疏矩阵的运算操作(矩阵的乘法)

未完待续。。。

猜你喜欢

转载自blog.csdn.net/zichen_ziqi/article/details/80861652