矩阵(一)

来源:互联网 发布:淘宝女装品牌推荐 编辑:程序博客网 时间:2024/09/21 09:28

特殊矩阵

对称矩阵


三角矩阵:

假设数组b用来存储矩阵的元素,则矩阵元素的下标(i,j)与该元素在数组b中的存储位置k之间有如下关系:

稀疏矩阵

包含大量零元素的矩阵称为稀疏矩阵,其经常出现在以下领域:大规模集成电路设计、电力输配系统、图像处理、城市规划等。
对此可只存储非零元素,对这些非零元素可采取顺序或链接的方式存储。

稀疏矩阵的顺序表示:三元组表示法
矩阵的元素aij可以看成一个三元组<i,j,v>,i为行号,j为列号,v为元素值
三元组表示的C语言描述:

#define MaxSize 101typedef int T;typedef struct term//三元组类型{int Row,Col;T Value;}Term;typedef struct triples//三元组表类型{int  Rows,Cols,NonZeros;//矩阵的行数、列数、非零元素的个数Term Elements[MaxSize];}Triples;typedef Triples SparseMatrix;
除了三元组表示方式外,还有伪地址方式,非零元素按行优先顺序的存储在一位数组中,元素aij在一位数组中的下标。
Loc(aij) = i*n+j; (0<=i<=n-1.0<=j<=n-1)

稀疏矩阵的转置


如图为一稀疏矩阵,其三元组表为:
(1)普通法:
若采用普通的二维数组来存储时,求解矩阵Am*n的转置矩阵An*m的程序段:

for(int i=0;i<m;i++)for(int j=0;j<m;j++)B[j][i] = A[i][j];



其时间复杂度为O(m*n)
(2)方法一:

将原数组中的每一个元素的行列交换得到数组B,然后在数组B中,将所有元素按行号进行排列,这里矩阵的转置时间取决于排序时间,典型的排序算法的时间复杂度为O(t^2)或O(t lb t),t为非零元素的个数
(3)方法二:

对数组A 进行n次扫描,第一遍取矩阵A的第0列元素,得到转置矩阵B的第0行元素,第i遍取出A的第i-1 列元素,得到B的第i-1 行元素,依次存入数组B中,此方法的时间复杂度为O(n*t)t为非0元素个数
(4)快速转置算法:

快速转置算法通过适当增加存储空间达到节省时间的目的。
快速转置算法使用数组k,k[i]为矩阵A中第i列的第一个非零元素在数组B中存放的位置。数组k的长度为矩阵的列数n。
例:k[3] = 5 表示矩阵A的第三列的第一个非零元素a03 = 22 在数组B的下标为5。为了得到数组k需要知道它的长度,于是用另外一个数组num保存矩阵A中个列的非0元素的个数
例:num[2]存放矩阵A的第2列非0元素的个数,即转置矩阵B第2行非零元素的个数。
数组num的值有以下语句求得:

for(int i=0;i<Col;i++)        num[i] = 0; //初始化为0for(i = 0;i <nonzeros;i++)//对所有非0元素num[a.Elements[i].Col]++;//将对应行的个数加一
当数组num的值已经计算出,则数组k可以简单地由以下递推公式计算

k[0] = 0;                   //B的第0行的第一个非0元素始终存放在下标为0的位置k[i] = k[i-1] + num[i-1];  (1<= i <n)
见下列语句:

k[0] = 0;for(int i=1;i<cols;i++)k[i] = k[i-1] + num[i-1]  (1<= i <n)


对于原数组,计算num和k的结果见下表:

有了数组k只需对A扫描一次即可完成转置。完成这项工作的程序段如下:

有了数组k只需对A扫描一次即可完成转置。完成这项工作的程序段如下:for(int i=0;i<nonzeros;i++){j=k[a.Elements[i].Col]++;//获取元素的下标,加一定位到数组B的具体位置,若第二次出现一个与第一在同一行的元素,//因第一次操作完后,下标志加了一,因此将存在第一个元素的后面。b.Elements[j].Row = a.Elements[i].Col;//分别复制数据b.Elements[j].Col = a.Elements[i].Row;b.Elements[j].Value = a.Elements[i].Value;}
下面给出稀疏矩阵的快速转置程序:

TriplesTripose(Triples a)//三元表a为参数{Triples b;//创建三元表b为转置矩阵int num[MAX_COL];//存放每一列的非零元素的个数int k[MAX_COL];int i,j;int cols = a.Cols;int nonzeros = a.NonZeros;b.Rows = a.Cols;//行、列转置b.Cols = a.Rows;b.NonZeros = a.NonZeros;if(nonzeros>0){for(i = 1;i<cols;i++)k[i] = k[i-1]+num[i-1];//计算每一列第一个元素的位置for(i = 0;i<nonzeros;i++){j=k[a.Elements[i].Col]++;b.Elements[j].Row = a.Elements[i].Col;//分别复制数据b.Elements[j].Col = a.Elements[i].Row;b.Elements[j].Value = a.Elements[i].Value;}}return b;}
其时间复杂度为O(Cols+NonZeros);





0 0
原创粉丝点击