[DataStructure]稀疏矩阵的三元组存储及乘法运算

P.S.我去、、我大作业不会打成系数矩阵了吧!!!!!!!!!!!

一、题目描述:

对于一个Rows X Columns稀疏矩阵,使用三元组的方法进行存储。

并在此基础上计算矩阵的乘法

二、解题报告

1.建立结构_Matrix

1 MAXVALUE为预估零元峰值个数,
2 struct _Matrix
3 {
4     int Sum;//实际输入总非零点数
5     int Rows,Columns;//矩阵行数,列数
6     double Data[MAXVALUE+1];//数据域,第i个数据的值
7 int Row[MAXVALUE+1],Column[MAXVALUE+1];
8 //第i个数据是第Row[i]行,Column[i]列
9 };

由此,可新建N个矩阵数组

_Matrix Matrix[N+1];

实际存储,需要运算的为Matrix[1]、Matrix[2],答案临时存储于Matrix[0]

2.主程序框架

1 int main()
2 {
3    Init();//初始化Matrix
4     for (int i=1;i<=N;++i)
5       InputData(i);//读入N(#define N 2)个Matrix
6     MultiplyMatrix(1,2);
7     OutputData();
8     return 0;
9 }

3.初始化过程Init();

1 /*初始化系数矩阵,Data,行、列矩阵指针Row、Column*/
2 void Init()
3 {
4     for (int j=1;j<=N;++j)
5       for (int i=0;i<=MAXVALUE;++i)
6         Matrix[j].Data[i]=Matrix[j].Row[i]=Matrix[j].Column[i]=0;
7 }

4.读入模块InputData(int i);

 1 void InputData(int i)
 2 {
 3     cout<<"请输入第"<<i<<"个矩阵"<<endl;
 4     cout<<"请输入矩阵的行数和列数"<<endl;
 5     cin>>Matrix[i].Rows>>Matrix[i].Columns;
 6     cout<<"请依次输入矩阵元素,-1为结束标志"<<endl;
 7     while (1)
 8     {
 9         cin>>Matrix[i].Row[++Matrix[i].Sum];//行指标,每一个非零元个数加1
10         if (Matrix[i].Row[Matrix[i].Sum]==-1)//-1为终止标志
11         {
12            --Matrix[i].Sum;//多读了个-1,所以Sum--
13            break;
14         }
15         cin>>Matrix[i].Column[Matrix[i].Sum];//读入列数指标
16         cin>>Matrix[i].Data[Matrix[i].Sum];//读入系数值
17     }
18 }
19 P.S.关于读入方法的声明
20     cout<<"读入方法如下:"<<endl;    cout<<"输入矩阵的行数和列数"<<endl;
21     cout<<"然后依次读入元素"<<endl; cout<<"第i行,第j列的值为Value"<<endl;
22     cout<<"则输入i j Value"<<endl; cout<<"输入-1时结束对本矩阵读入"<<endl;
23     cout<<"如对矩阵12 0 0"<<endl;
24     cout<<"         0 0 1"<<endl;
25     cout<<"         0 0 0"<<endl;
26     cout<<"请输入:3 3   "<<endl;
27     cout<<"请输入:1 1 12"<<endl; cout<<"       2 3 1 "<<endl;
28     cout<<"       -1    "<<endl;

5.矩阵乘法模块MultiplyMatrix(_Matrix A,B);

思想:依照矩阵乘法原则,通过O(N^2)查找对比,

将需要进行乘法的对应项相乘,结果存放在Matrix[0]尾三元组

然后将相同项相加,将Matrix[0]排序以便于输出。实际编写时,将本行写在输出中。

即只对最初结果三元组进行行、列从小到大排序,合并工作交由输出解决。

 1 void MultiplyMatrix(int N1,int N2)
 2 {    if (Matrix[N1].Columns != Matrix[N2].Rows) //判断是否可乘
 3       {
 4             cout<<"矩阵不可乘!请检查输入"<<endl;
 5             return ;
 6       }
 7     Matrix[0].Rows=Matrix[N1].Rows;
 8     Matrix[0].Columns=Matrix[N2].Columns;
 9     //根据矩阵乘法规则确定所得答案矩阵行列指标
10     n=0;//初始化计数器
11     /*时间复杂度O(N1.Sum*N2.Sum)*/
12     for (int i=1;i<=Matrix[N1].Sum;++i)
13         for (int j=1;j<=Matrix[N2].Sum;++j)
14            if (Matrix[N1].Column[i]==Matrix[N2].Row[j])
15 //1矩阵列指标==2矩阵行指标时,相乘
16            {
17             Matrix[0].Data[++n]=Matrix[N1].Data[i]*Matrix[N2].Data[j];
18             Matrix[0].Row[n]=Matrix[N1].Row[i];//行为1矩阵对应行
19             Matrix[0].Column[n]=Matrix[N2].Column[j];//列为2矩阵对应列
20            }
21      qSort(1,n);//按行指标对答案矩阵三元组进行QuickSort
22      /*   ///试图对行指标相同的进行处理,
23      for (int i=1;i<=n;++i)
24         for (int j=i+1;j<=n;++j)
25           if (Matrix[0].Row[i]!=Matrix[0].Row[j])
26              {   if (i+1==j) break;
27                  else{qSort2(i,j-1);//按列指标对答案矩阵三元组QuickSort
28                      i=j-1;
29                      break;
30                     }
31              } */
32       ///我这一段排序好像有点儿bug,一开始Test的时候是对的,交报告前随便写了个点儿发现错了、23333求大神帮忙指正
33 }

6.输出模块OutputData();

 1 void OutputData()
 2 {
 3   for (int i=1;i<=n;++i)
 4   { //合并格元素,已被用的行列指标赋值-1标记
 5 if (Matrix[0].Row[i]==Matrix[0].Row[i+1] && Matrix[0].Column[i]==Matrix[0].Column[i+1])
 6            {
 7                  Matrix[0].Row[i]=Matrix[0].Column[i]=-1;
 8               Matrix[0].Data[i+1]+=Matrix[0].Data[i];
 9            }
10   }
11     cout<<"按照读入三元组方式输出答案"<<endl;
12     for (int i=1;i<=n;++i)
13     {
14         if (Matrix[0].Row[i]!=-1)
15 {
16 cout<<"Ans["<<Matrix[0].Row[i]<<‘,‘;
17 cout<<Matrix[0].Column[i]<<"]="<<Matrix[0].Data[i]<<endl;
18        }
19 }
20 cout<<"按照矩阵方式输出答案"<<endl;
21 ///因为Matrix[0]已排序,故可顺次输出;不存在的即输出0;
22     int S=1;
23     for (int i=1;i<=Matrix[0].Rows;++i)
24     { for (int j=1;j<=Matrix[0].Columns;++j)
25           {  while  (Matrix[0].Row[S]==-1) ++S;
26             if (Matrix[0].Row[S]!=i || Matrix[0].Column[S]!=j)
27               cout<<0<<‘\t‘;
28             else
29             { cout<<Matrix[0].Data[S]<<‘\t‘;
30               ++S;
31             }
32           }
33         cout<<‘ ‘<<endl;
34     }
35 }

7.完整代码

  1 /*
  2    By
  3      Iris.Catch-22.S、`
  4      Dept. of Mathematics,
  5      School of Science,
  6      HIT
  7    December,2015
  8 */
  9 #include<iostream>
 10 using namespace std;
 11 void CopyRight()
 12 {
 13    cout<<"------------By ICS,HIT,2015/12-------------"<<endl;
 14    cout<<"---------------稀疏矩阵乘法----------------"<<endl;
 15    cout<<"-----------------Ver 1.0.0-----------------"<<endl;
 16
 17 }
 18 #define MAXVALUE 100000
 19 #define N 2
 20 struct _Matrix
 21 {
 22     int Sum;//总非零点数
 23     int Rows,Columns;//行数,列数
 24     double Data[MAXVALUE+1];//数据域,第i个数据的值
 25 int Row[MAXVALUE+1],Column[MAXVALUE+1];
 26 //第i个数据是第Row[i]行,Column[i]列
 27 };
 28
 29 /*新建矩阵数组*/
 30 _Matrix Matrix[N+1];
 31 int n;
 32
 33 /*Swap交换两个Double数*/
 34 void Swap(double &a,double &b)
 35 {
 36 double c=a;    a=b;    b=c;
 37 }
 38 /*重载Swap交换两个整数*/
 39 void Swap(int &a,int &b)
 40 {
 41     int c=a;    a=b;    b=c;
 42 }
 43 /*QuickSort 行排列从小到大*/
 44 void qSort(int l,int r)
 45 {
 46     int i=l;
 47     int j=r;
 48     int Mid=Matrix[0].Row[(l+r)>>1];
 49     do
 50     {
 51       while (Matrix[0].Row[i]<Mid) ++i;
 52       while (Mid<Matrix[0].Row[j]) --j;
 53       if (i<=j)
 54       {
 55         Swap(Matrix[0].Data[i],Matrix[0].Data[j]);
 56         Swap(Matrix[0].Row[i],Matrix[0].Row[j]);
 57         Swap(Matrix[0].Column[i],Matrix[0].Column[j]);
 58         ++i;
 59         --j;
 60       }
 61     }  while (i<=j);
 62     if (i<r) qSort(i,r);
 63     if (l<j) qSort(l,j);
 64 }
 65 /*QuickSort 行相同,列排列从小到大*/
 66 void qSort2(int l,int r)
 67 {
 68     int i=l;
 69     int j=r;
 70     int Mid=Matrix[0].Column[(l+r)>>1];
 71     do
 72     {
 73       while (Matrix[0].Column[i]<Mid) ++i;
 74       while (Mid<Matrix[0].Column[j]) --j;
 75       if (i<=j)
 76       {
 77         Swap(Matrix[0].Data[i],Matrix[0].Data[j]);
 78         Swap(Matrix[0].Column[i],Matrix[0].Column[j]);
 79         ++i;
 80         --j;
 81       }
 82     }  while (i<=j);
 83     if (i<r) qSort2(i,r);
 84     if (l<j) qSort2(l,j);
 85 }
 86
 87 /*初始化系数矩阵,Data,行、列矩阵指针Row、Column*/
 88 void Init()
 89 {
 90     for (int j=1;j<=N;++j)
 91       for (int i=0;i<=MAXVALUE;++i)
 92         Matrix[j].Data[i]=Matrix[j].Row[i]=Matrix[j].Column[i]=0;
 93 }
 94 /*读入数据*/
 95 void InputData(int i)
 96 {
 97     cout<<"请输入第"<<i<<"个矩阵"<<endl;
 98     cout<<"请输入矩阵的行数和列数"<<endl;
 99     cin>>Matrix[i].Rows>>Matrix[i].Columns;
100     cout<<"请依次输入矩阵元素,-1为结束标志"<<endl;
101     while (1)
102     {
103         cin>>Matrix[i].Row[++Matrix[i].Sum];//读入行指标,每读入一个非零元个数加1
104         if (Matrix[i].Row[Matrix[i].Sum]==-1)//-1为终止标志
105         {
106            --Matrix[i].Sum;//多读了个-1
107            break;
108         }
109         cin>>Matrix[i].Column[Matrix[i].Sum];//读入列数指标
110         cin>>Matrix[i].Data[Matrix[i].Sum];//读入系数值
111     }
112 }
113
114 /*测试输出*/
115 /*
116 void COUT(int Head,int Tail)
117 {
118     cout<<"---------------------"<<Head<<‘ ‘<<Tail<<"--------------------"<<endl;
119     for (int i=Head;i<=Tail;++i)
120       cout<<Matrix[0].Row[i]<<‘ ‘<<Matrix[0].Column[i]<<‘ ‘<<Matrix[0].Data[i]<<endl;
121     cout<<"--------------------------------------------------"<<endl;
122 }
123 */ //测试输出
124 void MultiplyMatrix(int N1,int N2)
125 {
126     if (Matrix[N1].Columns != Matrix[N2].Rows) //判断是否可乘
127       {
128             cout<<"矩阵不可乘!请检查输入"<<endl;
129             return ;
130       }
131     Matrix[0].Rows=Matrix[N1].Rows;
132     Matrix[0].Columns=Matrix[N2].Columns;
133     //根据矩阵乘法规则确定所得答案矩阵行列指标
134     n=0;//初始化计数器
135     /*时间复杂度O(N1.Sum*N2.Sum)*/
136     for (int i=1;i<=Matrix[N1].Sum;++i)
137         for (int j=1;j<=Matrix[N2].Sum;++j)
138            if (Matrix[N1].Column[i]==Matrix[N2].Row[j])
139 //1矩阵列指标==2矩阵行指标时,相乘
140            {
141             Matrix[0].Data[++n]=Matrix[N1].Data[i]*Matrix[N2].Data[j];
142             Matrix[0].Row[n]=Matrix[N1].Row[i];//行为1矩阵对应行
143             Matrix[0].Column[n]=Matrix[N2].Column[j];//列为2矩阵对应列
144            }
145      qSort(1,n);//按行指标对答案矩阵三元组进行QuickSort
146 /*
147      /*对行指标相同的进行处理*/
148      //COUT(1,n);
149      for (int i=1;i<=n;++i)
150         for (int j=i+1;j<=n;++j)
151           if (Matrix[0].Row[i]!=Matrix[0].Row[j])
152              {
153                  if (i+1==j) break;
154                  else
155                  {
156                      // COUT(i,j-1);
157                      qSort2(i,j-1);
158                      //COUT(i,j-1);
159                      i=j-1;
160                      break;
161                  }
162              }
163 */ ///本段待修正、、、、、
164 }
165 void OutputData()
166 {
167     /*
168     for (int i=1;i<=n;++i)
169     {
170         if (Matrix[0].Row[i]!=-1)
171         cout<<Matrix[0].Data[i]<<‘-‘<<Matrix[0].Row[i]<<‘-‘;
172 cout<<Matrix[0].Column[i]<<endl;
173     }
174     */ //原始数据
175     for (int i=1;i<=n;++i)
176 {
177 if(Matrix[0].Row[i]==Matrix[0].Row[i+1]&&Matrix[0].Column[i]==Matrix[0].Column[i+1])
178            {
179                  Matrix[0].Row[i]=Matrix[0].Column[i]=-1;
180               Matrix[0].Data[i+1]+=Matrix[0].Data[i];
181            }
182     }
183     cout<<"按照读入三元组方式输出答案"<<endl;
184     for (int i=1;i<=n;++i)
185     {
186         if (Matrix[0].Row[i]!=-1)
187             cout<<"Ans["<<Matrix[0].Row[i]<<‘,‘<<Matrix[0].Column[i]<<"]="<<Matrix[0].Data[i]<<endl;
188     }
189 /* cout<<"按照读入矩阵方式输出答案"<<endl;
190     int S=1;
191     for (int i=1;i<=Matrix[0].Rows;++i)
192     {  for (int j=1;j<=Matrix[0].Columns;++j)
193           {
194             while  (Matrix[0].Row[S]==-1) ++S;
195             if (Matrix[0].Row[S]!=i || Matrix[0].Column[S]!=j)
196               cout<<0<<‘\t‘;
197             else
198             {
199               cout<<Matrix[0].Data[S]<<‘\t‘;
200               ++S;
201             }
202           }
203         cout<<‘ ‘<<endl;
204     }
205 }*/
206 int main()
207 {    CopyRight();
208     cout<<"读入方法如下:"<<endl;
209     cout<<"输入矩阵的行数和列数"<<endl;
210     cout<<"然后依次读入元素"<<endl;
211     cout<<"第i行,第j列的值为Value"<<endl;
212     cout<<"则输入i j Value"<<endl;
213     cout<<"输入-1时结束对本矩阵读入"<<endl;
214     cout<<"如对矩阵12 0 0"<<endl;
215     cout<<"         0 0 1"<<endl;
216     cout<<"         0 0 0"<<endl;
217     cout<<"请输入:3 3   "<<endl;
218     cout<<"请输入:1 1 12"<<endl;
219     cout<<"       2 3 1 "<<endl;
220     cout<<"       -1    "<<endl;
221     Init();
222     for (int i=1;i<=N;++i)
223       InputData(i);
224     MultiplyMatrix(1,2);
225     OutputData();
226     return 0;
227 }

......

反正排序又被我搞的乱七八糟的……

QSort程序还是学期初手改的当初省实验王乃广老师教的那个快排(233333333)

然后对Qsort没什么心情研究了

结果今年DataStructure居然玩漏了没时间讲Sort了……

话说HuffManTree啊、查找啊、排序啊、什么的不都可以在算法课讲吗(hhhhh我知道你歧视小学期)

唉、

-----Done By Iris.Catch-22.S、`

时间: 2024-08-05 11:00:15

[DataStructure]稀疏矩阵的三元组存储及乘法运算的相关文章

稀疏矩阵的三元组顺序表存储及矩阵相乘算法小结

稀疏矩阵的三元组顺序表存储及矩阵相乘算法小结 巧若拙(欢迎转载,但请注明出处:http://blog.csdn.net/qiaoruozhuo) 一:稀疏矩阵的三元组顺序表数据结构 typedef int ElemType; typedef struct { intx, y;  //该非零元素的行下标和列下标 ElemTypee; //该非零元素的值 } Triple; typedef struct { Tripledata[MAXSIZE]; //非零元素三元组顺序表 intmu, nu, t

c++稀疏矩阵的压缩存储

稀疏矩阵 M*N的矩阵 其中有效值的个数远小于无效值的个数 且分布没有规律 Eg: int array [6][5] =     {{1, 0, 3, 0, 5}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {2, 0, 4, 0, 6}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}}; 稀疏矩阵的压缩存储 压缩存储值存储极少数的有效数据.使用{row,col,value}//行 列 值三元组存储每一个有效 数据,三元组按原矩阵中的位置,以行优先级

稀疏矩阵的压缩存储及转置算法

矩阵(Matrix)是一个按照长方阵列排列的复数或实数集合. 稀疏矩阵:有效数据远少于无效数据. eg:规定无效数据为 0 1 0 0 0 0 0 0 0 0 2 0 3 0 0 0 4 0 0 0 0 上述矩阵则可称为一个稀疏矩阵 我们在学习C语言的时候已经见过并使用过矩阵,其实它在我们的编程语言里可以翻译成二维数组,由于稀疏矩阵的有效数据十分的少,完全存储十分耗费我们的空间,所以我们选择只存储它的有效数据位,所以我们可以直接使用一维数组将其存储起来,但是我们必须让别人在看它时还能知道它是一个

对称矩阵、稀疏矩阵的压缩存储

1)对称矩阵的压缩存储 对称矩阵顾名思义就是符合行和列的个数相同,并且矩阵中存储的数据上三角和下三角中对应位置上的元素值是相等的.为了能够减少存储的空间,我们可以只存储上三角矩阵.或者下三角矩阵中的元素,这样就能够极大地节省空间的浪费.下面是对称矩阵的示列: 假设对称矩阵为n*n,这里以行优先存储下三角矩阵,总共需要存储的元素有n*(n+1)/2个元素,从而将n*n个元素压缩到n*(n+1)/2大小的空间中. 下面是具体的程序实现: --symmetric.h文件 //实现对称矩阵 #inclu

数据结构之自建算法库——稀疏矩阵的三元组表示

本文针对数据结构基础系列网络课程(5):数组与广义表中第3课时稀疏矩阵的三元组表示. 稀疏矩阵的三元组表示相关的算法库采用程序的多文件组织形式,包括两个文件: 1.头文件:tup.h,包含定义稀疏矩阵的三元组表示数据结构的代码.宏定义.要实现算法的函数的声明: #ifndef TUP_H_INCLUDED #define TUP_H_INCLUDED #define M 6 #define N 7 #define MaxSize 100 //矩阵中非零元素最多个数 typedef int Ele

稀疏矩阵的压缩存储及转置

没有经过处理的稀疏矩阵其实就是一个特殊的二维数组,数组中的大部分元素是0或者其他类型的非法值,只有少数几个非零元素. 为了实现压缩存储,可以只存储稀疏矩阵的非0元素.在存储稀疏矩阵中的非0元素时,必须要存储该元素的行列号以及元素值.我们可以封装一个三元组类来存储这些元素. //三元组 template<class T> struct Triple { size_t _row;   //行 size_t _col;   //列 T _value;      //值 Triple<T>

数据结构(二):线性表的使用原则以及链表的应用-稀疏矩阵的三元组表示

上一篇博文中主要总结线性表中的链式存储结构实现,比如单向链表.循环链表,还通过对比链表和顺序表的多项式的存储表示,说明链表的优点.可以参看上篇博文http://blog.csdn.net/lg1259156776/article/details/47018813 下面先对没有介绍的链表中的双链表进行介绍,并通过稀疏矩阵的三元组的链式结构来深入理解较为复杂的链表存储结构.最后对三次博文所讲述的内容进行梳理,以帮助在实际应用中选择最合适的存储结构:顺序表和链表,来组织实现自己的算法和功能. 双向链表

稀疏矩阵的压缩存储和转置

1.稀疏矩阵:M*N的矩阵,矩阵中有效值的个数远小于无效值的个数,且这些数据的分布没有规律. 2.稀疏矩阵的压缩存储:压缩存储值存储极少数的有效数据. 由于非零元素分布没有任何规律,所以在进行压缩存储的时侯需要存储无效值的同时还要存储有效元素在矩阵中的位置,即有效元素所在的行号和列号,也就是在存储某个元素比如aij的值的同时,还需要存储该元素所在的行号i和它的列号j,这样就构成了一个三元组(i,j,aij)的线性表. 使用{ row, col, value }三元组存储每一个有效数据,三元组按原

稀疏矩阵的压缩存储与转置

稀疏矩阵:矩阵中大多数元素为0的矩阵(本文以行序为主序) 稀疏矩阵的三元组表述法: 类型结构: template <typename T> struct Triple { int _row; int _col; T _value; }; template <typename T> class SparseMatrix { public: SparseMatrix<T>::SparseMatrix(); SparseMatrix(const T* array, size_