稀疏矩阵三元组表示法的倒置

来源:互联网 发布:websocketserver java 编辑:程序博客网 时间:2024/06/07 12:44

稀疏矩阵的概念及三元组表示法

如果一个矩阵中的很多元素的值为零,即零元素的个数远远大于非零元素的个数时,称该矩阵为稀疏矩阵

由于矩阵中零元素过多,若用一般方法对稀疏矩阵进行存储会造成空间的大大浪费,因此,我们在存储稀疏矩阵的时候,只需要对非零元素进行存储

根据存储时所附加信息的不同,稀疏矩阵的顺序存储方式包括:三元组表示法、带辅助行向量的二元组表示法和伪地址表示法。本文采取三元组表示法对稀疏矩阵进行存储。

三元组表示法实际上就是一个二维数组,即将稀疏矩阵中单个非零元的信息(所在行、所在列、数值)用一个数组进行才能存储,再将所有存有单个非零元的数组再用一个数组进行存储。需要注意的是,二维数组开始的第一串信息存的是整个稀疏矩阵的信息(即矩阵的规格以及非零元个数 , 并且每个非零元素需按照行号递增、同一行的非零元素按列号递增的顺序存放。

举个栗子:定义一个76 的矩阵A。

A=00301200000000050000021020000010000000000040

用可用二维数组B[8][3]对其进行存储,其中B[0][0~2]存放矩阵信息,B[1~7][0~2]存放非零元素的信息。相应表格如下:

B 0 1 2 0 7 6 7 1 0 2 -5 2 0 4 1 3 1 3 2 4 2 0 3 5 4 0 12 6 5 5 4 7 6 2 21

稀疏矩阵的倒置及相应三元组表示法的实现

一般矩阵倒置就是将下标换一下,但是三元组表示法要按行号递增、相同行按列号递增,所以直接调换下标不可以实现稀疏矩阵的倒置,我们还要将坐标交换后的元素数组对应地存入数组相应位置,如将B[1][0~2]0行2列的元素转置后变为C[?][0~2]2行0列,将它对应的存到C数组的?下标处。由于转置前后数组非零元素的个数不会发生改变,所以我们需要知道当前转置的元素前面有多少个元素。一种方法是定义两个数组分别用来存放转置后矩阵每行非零元素的个数以及每行首个非零元素在三元组C[][0~2]的起始位置,类似于首地址加偏移量的方法。

具体实现
定义数组x[size],用来存放矩阵转置后每行非零元个数(也就是转置前每列非零元个数),其中数组下标就等于转置前矩阵的列号,这样通过对列号的直接访问就可以知道当前列非零元个数;
y[size]用来存放转置后每行首个非零元素在三元组C[][0~2]的起始位置,其中数组下标表示转置前矩阵的列号。而y[size] = y[size-1] + x[size-1],其中y[0]初始为0.因为数组下标从0开始,即代表数组第一个元素的在C[0][ ]。

代码实现:

typedef struct {    int data[100][100];    int m, n;} matrix;   //表示稀疏矩阵的类型typedef int spmatrix[100][3];   //稀疏矩阵对应的三元组void transpMatrix (spmatrix B, spmatrix C) {    int i, j, t, m, n;    int x[100];     //用以存放转置后每行非零元个数    int y[100];     //用以存放转置后每行首个非零元在单元组中的位置    m = B[0][0];    //记录行    n = B[0][1];    //记录列    t = B[0][2];    //记录矩阵非零元个数    C[0][0] = n;    //写入行    C[0][1] = m;    //写入列    C[0][2] = t;    //写入非零元个数    if(t > 0) {        for(i=0; i<n; i++) x[i] = 0;    //假设转置后每行均无非零元        for(i=1; i<=t; i++) x[B[i][1]]++;   //记录转置后每行非零元个数        y[0] = 1;                       //假设转置后第0行存在非零元则首非零元个在三元组中位于第一个位置        for(i=1; i<n; i++) y[i] = y[i-1] + x[i-1];  //记录每行首个非零元在三元组中的位置        for(i=1; i<=t; i++) {   //需注意循环条件的变化            j = B[i][1];            C[j][0] = B[i][1];  //坐标交换            C[j][1] = B[i][0];  //坐标交换            C[j][2] = B[i][2];  //值写入            y[B[i][1]] = j + 1; //转置后B[i][1]行已存入一个元素,位置+1,若该行还有其他非零元,则会按序存入        }    }}

此处建议大家对代码部分进行深入的解读,必要时可取例子代入以帮助理解。


本文为本人原创,欢迎指点批评~

欢迎各位来本人的博客金傲Asher的个人博客 参观,所有文章将第一时间发布在上面的博客,csdn只会偶尔搬运。

原创粉丝点击