解决数组的编程问题

目录

特殊矩阵

稀疏矩阵

用顺序表存储稀疏矩阵的三元组:

用十字链表存储稀疏矩阵的三元组:


1.数组的定义

数组是由n(n>=1)个相同类型的数据元素组成的有限序列,数组中的每一个数据通常为数据元素。数组中的元素可以通过下标随机访问,其中下标的个数由数组的维数决定。

2.数组的特点

数组中的数据元素数目是确定的。一旦定义了一个数组,其数据元素的数目不再增减。

数组中的数据元素具有相同的数据类型。

扫描二维码关注公众号,回复: 5425279 查看本文章

数组的中的每个数据元素都和一组唯一的下标值对应。

数组是一种随机存储结构,可随机存储数组中的任意数据元素。

3.用顺序存储结构存储数组

由于数组一般不进行插入或删除操作,也就是说,一旦建立了数组,则结构中的数据元素个数和元素之间的关系就不再发生变动,变动的只能是数据元素的值。因此,采用顺序存储结构表示数组是自然而然的事了。

在C#中,数组实际上是对象。System.Array是所有数组类型的抽象基类型。当在程序中声明并创建了一个数组后,该数组就是一个Array类型的实例。

压缩存储:就是对矩阵中值相同的元素只分配一个存储空间,对零元素不分配空间。对于需要压缩存储的矩阵可分为特殊矩阵稀疏矩阵

特殊矩阵

含义:那些具有相同值元素或零元素在矩阵中分布有一定规律的矩阵。常见特殊矩阵有:对角矩阵,三对角矩阵,下三角矩阵,上三角矩阵,对称矩阵

特殊矩阵示意图:

特殊矩阵的压缩存储:(不懂!)

稀疏矩阵

含义:零元素数据远多于非零元素数目,且零元素分布无规律的矩阵

由于非零元素分布没有任何规律,所以在进行压缩存储的时候需要存储非零元素值a(ij)的同时还要存储非零元素在矩阵中的位置,即非零元素所在的行号i和列号j,这样就构成了一个三元组(i,j, aij)的线性表。

以下三元组的线性表为:(0,0,2),(0,4,6),(0,7,7),(1,2,1),(2,2,2),(2,6,3),(3,5,8),(4,3,5),(5,1,9)

                              

三元组可以采用顺序表表示方法,也可以采用链式表示方法。

用顺序表存储稀疏矩阵的三元组:

namespace 用顺序表存储稀疏矩阵的三元组
{
    struct tupletype<T>
    {
        public int i;//行号
        public int j;//列号
        public T v;//元素值

        public tupletype (int i,int j,T v)
        {
            this.i = i;
            this.j = j;
            this.v = v;
        }
    }

    class spmatrix<T>
    {
        private int maxnum;//非零元素的最大个数
        private int md;//行数值
        private int nd;//列数值
        private int td;//非零元素的实际个数
        private tupletype<T>[] data;//存储三元组的值

        public int Maxnum { get => maxnum; set => maxnum = value; }
        public int Md { get => md; set => md = value; }
        public int Nd { get => nd; set => nd = value; }
        public int Td { get => td; set => td = value; }
        public tupletype<T>[] Data { get => data; set => data = value; }
        
        //初始化三元组顺序表
        public spmatrix() { }
        public spmatrix (int maxnum,int md,int nd)
        {
            this.Maxnum = maxnum;
            this.md = md;
            this.nd = nd;
            data = new tupletype<T>[Maxnum];
        }

        /// <summary>
        /// 设置三元组表元素的值
        /// </summary>
        /// <param name="i"></param>
        /// <param name="j"></param>
        /// <param name="v"></param>
        public void setData(int i,int j,T v)
        {
            data[td] = new tupletype<T>(i, j, v);
            td++;
        }

        /// <summary>
        /// 转置矩阵算法。未懂!
        /// </summary>
        /// <returns></returns>
        public spmatrix <T> Transpose()
        {
            spmatrix<T> N = new spmatrix<T>();
            N.maxnum = maxnum;
            N.nd = md;
            N.md = nd;
            N.td = td;
            N.data = new tupletype<T>[N.td];

            if (td != 0)
            {
                int q = 0; //控制转置矩阵的下标
                for (int col = 0; col < nd; col++) //扫描矩阵的列
                {
                    for (int p = 0; p < td; p++) //p控制被转置矩阵的下标
                    {
                        if (data [p].j ==col )
                        {
                            N.data[q].i = data[p].j;
                            N.data[q].j = data[p].i;
                            N.data[q].v = data[p].v;
                            q++;
                        }
                    }
                }
            }
            return N;
        }
    }
}

用十字链表存储稀疏矩阵的三元组:

用一维数组来描述稀疏矩阵所存在的缺点是,当创建这个一维数组时,必须知道稀疏阶段中的非零元素总数,虽然在输入矩阵时,这个数是已知的,但随着矩阵加法减法和乘法操作的执行,非零元素的数目会发生变化,因此如果不实际计算很难精确的知道非零元素的数目,但如果采用链式存储结构,就可以避免这种情况。

十字链表节点分为三类,一类是表结点,它有5个域组成,其中i和j存储的是结点所在的行和列,right和down存储的是指向十字链表中,该结点所有行和列的下一个节点的指针,v用于存放元素值;另一类结点为行头和列头结点,这个结点也由域组成,其中行和列的值均为0,没有实际意义,right和down的域用于在行方向和列方向上指向表结点,next用于指向下一个行或列的表头结点,最后一类结点称为总表头结点,这类结点与表头之类的结构和形式一样,只是他的i和j存放的是矩阵的行和列数。

十字链表结点结构:

十字链表中的每一行和每一年的链表。都是一个循环链表,都有一个表头结点。

一个稀疏矩阵的十字链表示意图:


 

猜你喜欢

转载自blog.csdn.net/qq_40323256/article/details/88072430