当前位置:首页 » 存储配置 » 稀疏矩阵存储c语言

稀疏矩阵存储c语言

发布时间: 2022-06-02 14:10:09

‘壹’ c语言根据以下描述编写一个程序使其能完成对稀疏矩阵的压缩与还原,即给定稀疏矩阵可以压缩存储一个三元组

这是数值代数中的问题,对于不同的稀疏矩阵有着不同的算法,你可查阅数值代数的书籍,找到对应的算法,根据算法就很好编写了

‘贰’ 用C语言写; 一个稀疏矩阵

#include<stdio.h>
#include<stdlib.h>
#define MAXSIZE 20

struct array
{
int r,c,v;
};

struct Tarray
{
array data[MAXSIZE];
int num;
int a[4][5];
}*p;

void creat_the_Tarray()//creat the array;
{
int i,j;
p=(Tarray*)malloc(sizeof(Tarray));//give the space the array;
p->num=0;//
printf(

‘叁’ 用C语言实现稀疏矩阵的除法

一般人在使用MATLAB时
对于矩阵的左除与右除很难正确的!区别出须要使用那一个
因此借此机会说明一下
希望能更大家多多讨论

矩阵之除法是有其特别的定义
下面是例子:
假设A矩阵为方矩阵,且有反矩阵存在;b为配合之列向量或行向量,x为与b同大小之未知向量。
则以矩阵表示之联立方程式可以表示如下:

A*x=b

利用两矩阵”左除”即 ” \ ”之意义可以获得上式之解,即:

x = A\b

换言之,利用这样的左除指令,可以解联立方程式。

反之若方程式写成另一种型式:

x*A=b

则其解可以用右除表示:

x=b/A

利用左除法,若A 方矩阵,则其乘幂是使用高斯递减法解A*x=b 之矩阵方程式。

若A 不为方矩阵,则其乘幂是使用欧斯侯德之正交法,以最小平方之方式就不足或过多变数系统求解。右除法与左除法之关系实际上可表示如下:

b/A = (A'\b')'

‘肆’ C语言课程设计:稀疏矩阵应用 要求:实现三元组,十字链表下的稀疏矩阵的加、转、乘的实现。

我刚写了一个稀疏矩阵的代码,如下
#include <iostream>
#include <iomanip>
using namespace std;

template<class T>
//三元组
struct Trituple
{
int row;
int col;
T val;
};
//稀疏矩阵声明
template<class T>
class SparseMatrix
{
public:
SparseMatrix(int maxt=100);
~SparseMatrix();
bool TransposeTo(SparseMatrix &);
bool AddTo(const SparseMatrix&);
bool TransposeTo_Faster(SparseMatrix&);
void Input();
void Output();
private:
Trituple<T>* data;
int rows,cols,terms;
int maxterms;
};
template<class T>
SparseMatrix<T>::SparseMatrix(int maxt)
{
maxterms=maxt;
data=new Trituple<T>[maxterms];
terms=rows=cols=0;
}
template<class T>
SparseMatrix<T>::~SparseMatrix()
{
if (data!=NULL)
{
delete[] data;
}
}
//普通转置
template<class T>
bool SparseMatrix<T>::TransposeTo(SparseMatrix &B)
{
if (terms>B.maxterms)
{
return false;
}
B.rows=cols;
B.cols=rows;
B.terms=terms;
if (terms>0)
{
int p=0;
for (int j=1;j<=cols;j++)
{
for (int k=0;k<terms;k++)
{
if (data[k].col==j)
{
B.data[p].row=j;
B.data[p].col=data[k].row;
B.data[p].val=data[k].val;
p++;
}
}
}
}
return true;
}
//快速转置
template<class T>
bool SparseMatrix<T>::TransposeTo_Faster(SparseMatrix& B)
{
if (terms>B.maxterms)
{
return false;
}
B.rows=cols;
B.cols=rows;
B.terms=terms;
if (terms>0)
{
int *num,*cpot;
num=new int[cols];
cpot=new int[cols];
for (int j=0;j<cols;j++)
{
num[j]=0;
}
for (int k=0;k<terms;k++)
{
num[data[k].col-1]++;
}
//求出B中每一行的起始下标cpot[]
cpot[0]=0;
for (int j=1;j<cols;j++)
{
cpot[j]=cpot[j-1]+num[j-1];
}
//执行转置操作
for (int p,k=0;k<terms;k++)
{
p=cpot[data[k].col-1]++;
B.data[p].row=data[k].col;
B.data[p].col=data[k].row;
B.data[p].val=data[k].val;
}
delete[] num;
delete[] cpot;
}
return true;
}
template<class T>
void SparseMatrix<T>::Input()
{
cout<<"intput the matrix' row:";
int row1;
cin>>row1;
cout<<"intput the matrix' col:";
int col1;
cin>>col1;
cout<<"input "<<row1<<"*"<<col1<<" matrix"<<endl;
int number;
rows=row1;
cols=col1;
for (int i=0;i<rows;i++)
{
for (int j=0;j<cols;j++)
{
cin>>number;
if (number!=0)
{
data[terms].row=i+1;
data[terms].col=j+1;
data[terms].val=number;
terms++;
}
}
}
}
template<class T> //输出好看,但是违背了最初的原则
void SparseMatrix<T>::Output()
{
T **tempArray=new T*[rows];
for (int i1=0;i1<rows;i1++)
{
tempArray[i1]=new int[cols];
}
for (int j=0;j<rows;j++)
{
for (int k=0;k<cols;k++)
{
tempArray[j][k]=0;
}
}
for (int i=0;i<terms;i++)
{
tempArray[data[i].row-1][data[i].col-1]=data[i].val;
}
for (int j=0;j<rows;j++)
{
for (int k=0;k<cols;k++)
{
cout<<setw(4)<<tempArray[j][k];
}
cout<<endl;
}
for (int l=0;l<rows;l++)
{
delete[] tempArray[l];
}
delete tempArray;
cout<<endl;
}
template<class T>
bool SparseMatrix<T>::AddTo(const SparseMatrix& B)
{
if (rows!=B.rows||cols!=B.cols)
{
return false;
}
bool flag=false;
int tempTerms=terms;
for (int i=0;i<B.terms;i++)
{
flag=false;
for (int j=0;j<tempTerms;j++)
{
if (data[j].col==B.data[i].col&&data[j].row==B.data[i].row)
{
data[j].val+=B.data[i].val;
flag=true;
}
}
if (flag==false)
{
data[++terms-1].col=B.data[i].col; //数组下标操作注意事项
data[terms-1].row=B.data[i].row;
data[terms-1].val=B.data[i].val;
}
}
return true;
}
int main()
{
cout<<"此程序演示稀疏矩阵的普通转置和快速转置操作"<<endl;
SparseMatrix<int> sm(50);
SparseMatrix<int> sm1(50);
SparseMatrix<int> sm2(50);
sm.Input();
cout<<"sm is"<<endl;
sm.Output();
sm.TransposeTo(sm1);
cout<<"Transposition of sm is "<<endl;
sm1.Output();
sm.TransposeTo_Faster(sm2);
cout<<"Transposition of sm is "<<endl;
sm2.Output();
SparseMatrix<int> sm3;
cout<<"input a new matrix"<<endl;
sm3.Input();
cout<<"sm3 is"<<endl;
sm3.Output();
if(sm.AddTo(sm3))
{
cout<<"after adding sm3 ,sm is"<<endl;
sm.Output();
}
else
cout<<"the two matrix can't add"<<endl;
cout<<"Good job!"<<endl;
system("pause");
return 0;
}

‘伍’ C语言数据结构稀疏矩阵的存储

//稀疏矩阵的十字链表存储表示
#include<stdio.h>
#include<stdlib.h>

typedef int ElemType;
typedef struct OLNode
{
int i,j; //该非零元的行(i)和列(j)下标
ElemType e; //该非零元
struct OLNode *right,*down; //该非零元所在行表和列表的后继链域
}OLNode,*OLink;
typedef struct
{
OLink *rhead,*chead; //行和列链表头指针向量基址CreateSMartix分配
int mu,nu,tu; //稀疏矩阵的行数(mu),列数(nu)和非零元数tu
}CrossList;

void CreateSMatrix(CrossList *M)
{
int m,n,t; //M行,N列,T非零元
int i,j,mi,mj,e;
OLink p,q;

printf("please enter matrix's row,column,element:\n");
scanf("%d %d %d",&m,&n,&t);//输入行数,列数,非零元个数
M->mu = m; M->nu = n; M->tu = t;
printf("\n");

if(!(M->rhead=(OLink*)malloc((m+1)*sizeof(OLink)))) exit(1);
if(!(M->chead=(OLink*)malloc((n+1)*sizeof(OLink)))) exit(1);
for(i=0;i<=m;++i) //初始化行,列头指针,使其为空链表
M->rhead[i] = NULL;
for(j=0;j<=n;++j)
M->chead[j] = NULL;
//按任意次序输入非零元
for(scanf("%d %d %d",&mi,&mj,&e); mi!=0;scanf("%d %d %d",&mi,&mj,&e))
{

if(!(p = (OLink)malloc(sizeof(OLNode)))) exit(1);
p->i = mi; p->j = mj; p->e = e; //赋值

if(M->rhead[mi]==NULL)
{

p->right = M->rhead[mi];
M->rhead[mi] = p;

}

else
{
//已存在结点和比结点插入小的情况
for(q=M->rhead[mi]; q->right && q->right->j<j; q=q->right);
p->right = q->right; q->right = p;

}//完成行插入

if(M->chead[mj]==NULL )
{
p->down = M->chead[mj];
M->chead[mj] = p;
}
else
{
for(q=M->chead[mj]; q->down && q->down->i<i; q=q->down);
p->down = q->down; q->down = p;
}//完成列插入
}// for
}
void AddSMatrix(CrossList *M,CrossList *N)
{
//M与N矩阵相加结果到M中
OLink pa,pb,hj[10],pre,p;//pa,pb指向矩阵M,N,hj,pre作为前驱指针,p是临时结点
int i,j;

pre = NULL;
for(j=1;j<=M->nu;++j) //hj取得M每列首地址
hj[j] = M->chead[j];
for(i=1;i<=M->mu;++i)
{
pa = M->rhead[i]; pb = N->rhead[i]; //分别指向行首地址
pre = pa;
while(pb)
{
//处理行的情况
if(pa==NULL || pa->j > pb->j) //pa的列比pb大时
{
p = (OLink)malloc(sizeof(OLNode));
p->i = pb->i; p->j = pb->j; p->e = pb->e; //p得到N上的值
if(M->rhead[p->i]==NULL)
{
M->rhead[p->i] = pre = p; p->right = NULL;
}
else
pre->right = p; //pa的前驱结点指向新结点p

p->right = pa; //新结点指向pa

pre = p;
//处理列
if(M->chead[p->j]==NULL) //列首地址为空
{
hj[p->j] = M->chead[p->j] = p; p->down = NULL;
}
else //列首地址不为空
{
p->down = hj[p->j]->down;
hj[p->j]->down = p;
hj[p->j] = p;

}//处理列

pb = pb->right;

}// else if pa
else if(pa->j < pb->j )//当pa的列比pb小时
{
pre = pa;pa = pa->right; //printf("pa==null?in pa->j<pb-j\n");
}
else //列相等的情况
{
pa->e += pb->e;
if(pa->e==0) //若相加等于0
{
//处理行
p = pa; //得到准备删除结点
if(pa->right) //pa有有后继结点则pre后移
{
pre->right = p->right;
pa = pa->right;
}
else pa = M->rhead[p->i] = NULL; //否则头指针置空

//处理列
if(M->chead[p->j]==p)
M->chead[p->j] = hj[p->j] = p->down;
else
{
//hj[p->j]->down = p->down;

hj[p->j]->down = p->down;
}
free(p);
}
pb = pb->right;
}
//处理列的情况
}//while pa
}
}
void PrintSMatrix(CrossList *M)
{
int i;
OLink dis;

printf("i j e\n");
for(i=1;i<=M->mu;++i)
{
dis = M->rhead[i];
while(dis)
{
printf("%d %d %d\t",dis->i,dis->j,dis->e);
dis = dis->right;
}
printf("\n");
}
}
void TransposePrint(CrossList *M)
{
int i;
OLink dis;

printf("i j e\n");
for(i=1;i<=M->nu;++i)
{
dis = M->chead[i];
while(dis)
{
printf("%d %d %d\t",dis->j,dis->i,dis->e);
dis = dis->down;
}
printf("\n");
}
}
int main(void)
{
CrossList M,N;

CreateSMatrix(&M);
printf("Matrix M:\n");
PrintSMatrix(&M);
TransposePrint(&M);

CreateSMatrix(&N);
printf("Matrix N:\n");
PrintSMatrix(&N);
printf("M + N = :\n");
AddSMatrix(&M,&N);
PrintSMatrix(&M);
TransposePrint(&M);

//PrintSMatrix(&M);
return 0;
}

输入
3 4 4

1 1 3
1 4 5
2 2 -1
3 1 2
0 0 0

3 4 4

1 3 4
2 2 7
3 1 -2
3 3 8
0 0 0

‘陆’ 用C实现:将二维数组中存放的稀疏矩阵压缩存储于三元组表中

悲剧了,三元组表我都不知道是什么。

‘柒’ 稀疏矩阵的转置运算用C语言

#include<string.h>

#include<ctype.h>
#include<malloc.h> // malloc()等
#include<limits.h> // INT_MAX等
#include<stdio.h> // EOF(=^Z或F6),NULL
#include<stdlib.h> // atoi()
#include<io.h> // eof()
#include<math.h> // floor(),ceil(),abs()
#include<process.h> // exit()
#include<iostream.h> // cout,cin
// 函数结果状态代码
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
// #define OVERFLOW -2 因为在math.h中已定义OVERFLOW的值为3,故去掉此行
typedef int Status; // Status是函数的类型,其值是函数结果状态代码,如OK等
typedef int Boolean; // Boolean是布尔类型,其值是TRUE或FALSE
typedef int ElemType;
// c5-2.h 稀疏矩阵的三元组顺序表存储表示
#define MAXSIZE 100 // 非零元个数的最大值
struct Triple
{
int i,j; // 行下标,列下标
ElemType e; // 非零元素值
};
struct TSMatrix
{
Triple data[MAXSIZE+1]; // 非零元三元组表,data[0]未用
int mu,nu,tu; // 矩阵的行数、列数和非零元个数
};
// bo5-2.cpp 三元组稀疏矩阵的基本操作,包括算法5.1(9个)
Status CreateSMatrix(TSMatrix &M)
{ // 创建稀疏矩阵M
int i,m,n;
ElemType e;
Status k;
printf("请输入矩阵的行数,列数,非零元素数:");
scanf("%d,%d,%d",&M.mu,&M.nu,&M.tu);
M.data[0].i=0; // 为以下比较顺序做准备
for(i=1;i<=M.tu;i++)
{
do
{
printf("请按行序顺序输入第%d个非零元素所在的行(1~%d),列(1~%d),元素值:",i,M.mu,M.nu);
scanf("%d,%d,%d",&m,&n,&e);
k=0;
if(m<1||m>M.mu||n<1||n>M.nu) // 行或列超出范围
k=1;
if(m<M.data[i-1].i||m==M.data[i-1].i&&n<=M.data[i-1].j) // 行或列的顺序有错
k=1;
}while(k);
M.data[i].i=m;
M.data[i].j=n;
M.data[i].e=e;
}
return OK;
}
void DestroySMatrix(TSMatrix &M)
{ // 销毁稀疏矩阵M
M.mu=0;
M.nu=0;
M.tu=0;
}
void PrintSMatrix(TSMatrix M)
{ // 输出稀疏矩阵M
int i;
printf("%d行%d列%d个非零元素。\n",M.mu,M.nu,M.tu);
printf("行 列 元素值\n");
for(i=1;i<=M.tu;i++)
printf("%2d%4d%8d\n",M.data[i].i,M.data[i].j,M.data[i].e);
}
Status CopySMatrix(TSMatrix M,TSMatrix &T)
{ // 由稀疏矩阵M复制得到T
T=M;
return OK;
}
int comp(int c1,int c2) // 另加
{ // AddSMatrix函数要用到
int i;
if(c1<c2)
i=1;
else if(c1==c2)
i=0;
else
i=-1;
return i;
}
Status AddSMatrix(TSMatrix M,TSMatrix N,TSMatrix &Q)
{ // 求稀疏矩阵的和Q=M+N
Triple *Mp,*Me,*Np,*Ne,*Qh,*Qe;
if(M.mu!=N.mu)
return ERROR;
if(M.nu!=N.nu)
return ERROR;
Q.mu=M.mu;
Q.nu=M.nu;
Mp=&M.data[1]; // Mp的初值指向矩阵M的非零元素首地址
Np=&N.data[1]; // Np的初值指向矩阵N的非零元素首地址
Me=&M.data[M.tu]; // Me指向矩阵M的非零元素尾地址
Ne=&N.data[N.tu]; // Ne指向矩阵N的非零元素尾地址
Qh=Qe=Q.data; // Qh、Qe的初值指向矩阵Q的非零元素首地址的前一地址
while(Mp<=Me&&Np<=Ne)
{
Qe++;
switch(comp(Mp->i,Np->i))
{
case 1: *Qe=*Mp;
Mp++;
break;
case 0: switch(comp(Mp->j,Np->j)) // M、N矩阵当前非零元素的行相等,继续比较列
{
case 1: *Qe=*Mp;
Mp++;
break;
case 0: *Qe=*Mp;
Qe->e+=Np->e;
if(!Qe->e) // 元素值为0,不存入压缩矩阵
Qe--;
Mp++;
Np++;
break;
case -1: *Qe=*Np;
Np++;
}
break;
case -1: *Qe=*Np;
Np++;
}
}
if(Mp>Me) // 矩阵M的元素全部处理完毕
while(Np<=Ne)
{
Qe++;
*Qe=*Np;
Np++;
}
if(Np>Ne) // 矩阵N的元素全部处理完毕
while(Mp<=Me)
{
Qe++;
*Qe=*Mp;
Mp++;
}
Q.tu=Qe-Qh; // 矩阵Q的非零元素个数
return OK;
}
Status SubtSMatrix(TSMatrix M,TSMatrix N,TSMatrix &Q)
{ // 求稀疏矩阵的差Q=M-N
int i;
for(i=1;i<=N.tu;i++)
N.data[i].e*=-1;
AddSMatrix(M,N,Q);
return OK;
}
Status MultSMatrix(TSMatrix M,TSMatrix N,TSMatrix &Q)
{ // 求稀疏矩阵的乘积Q=M*N
int i,j,h=M.mu,l=N.nu,Qn=0;
// h,l分别为矩阵Q的行、列值,Qn为矩阵Q的非零元素个数,初值为0
ElemType *Qe;
if(M.nu!=N.mu)
return ERROR;
Q.mu=M.mu;
Q.nu=N.nu;
Qe=(ElemType *)malloc(h*l*sizeof(ElemType)); // Qe为矩阵Q的临时数组
// 矩阵Q的第i行j列的元素值存于*(Qe+(i-1)*l+j-1)中,初值为0
for(i=0;i<h*l;i++)
*(Qe+i)=0; // 赋初值0
for(i=1;i<=M.tu;i++) // 矩阵元素相乘,结果累加到Qe
for(j=1;j<=N.tu;j++)
if(M.data[i].j==N.data[j].i)
*(Qe+(M.data[i].i-1)*l+N.data[j].j-1)+=M.data[i].e*N.data[j].e;
for(i=1;i<=M.mu;i++)
for(j=1;j<=N.nu;j++)
if(*(Qe+(i-1)*l+j-1)!=0)
{
Qn++;
Q.data[Qn].e=*(Qe+(i-1)*l+j-1);
Q.data[Qn].i=i;
Q.data[Qn].j=j;
}
free(Qe);
Q.tu=Qn;
return OK;
}
Status TransposeSMatrix(TSMatrix M,TSMatrix &T)
{ // 求稀疏矩阵M的转置矩阵T。算法5.1
int p,q,col;
T.mu=M.nu;
T.nu=M.mu;
T.tu=M.tu;
if(T.tu)
{
q=1;
for(col=1;col<=M.nu;++col)
for(p=1;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;
}
}
return OK;
}
Status FastTransposeSMatrix(TSMatrix M,TSMatrix &T)
{ // 快速求稀疏矩阵M的转置矩阵T。算法5.2
int p,q,t,col,*num,*cpot;
num=(int *)malloc((M.nu+1)*sizeof(int)); // 生成数组([0]不用)
cpot=(int *)malloc((M.nu+1)*sizeof(int)); // 生成数组([0]不用)
T.mu=M.nu;
T.nu=M.mu;
T.tu=M.tu;
if(T.tu)
{
for(col=1;col<=M.nu;++col)
num[col]=0; // 设初值
for(t=1;t<=M.tu;++t) // 求M中每一列含非零元素个数
++num[M.data[t].j];
cpot[1]=1;
for(col=2;col<=M.nu;++col) // 求第col列中第一个非零元在T.data中的序号
cpot[col]=cpot[col-1]+num[col-1];
for(p=1;p<=M.tu;++p)
{
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;
++cpot[col];
}
}
free(num);
free(cpot);
return OK;
}
void main()
{
TSMatrix A,B;
printf("创建矩阵A: ");
CreateSMatrix(A);
PrintSMatrix(A);
FastTransposeSMatrix(A,B);
printf("矩阵B(A的快速转置): ");
PrintSMatrix(B);
DestroySMatrix(A);
DestroySMatrix(B);
}

稀疏矩阵三元组转置,你参考下

热点内容
自动编译div 发布:2025-01-12 18:51:06 浏览:659
手机路由器如何登陆密码 发布:2025-01-12 18:35:41 浏览:464
电光猫无法连接服务器是什么原因 发布:2025-01-12 18:32:58 浏览:512
迷你世界测试服的密码从哪里打开 发布:2025-01-12 18:25:32 浏览:110
我的世界手游tis服务器 发布:2025-01-12 18:24:28 浏览:585
青海省分布式服务器云主机 发布:2025-01-12 18:12:03 浏览:476
英雄联盟安卓手机版怎么切换 发布:2025-01-12 18:10:53 浏览:381
q5尊享时尚型哪些配置 发布:2025-01-12 18:05:41 浏览:229
安卓版本哪里下载 发布:2025-01-12 18:05:39 浏览:557
mc服务器搭建搜不到 发布:2025-01-12 17:57:37 浏览:19