用十字链表和一般方法分别实现稀疏矩阵的乘法和加法

用十字链表和一般方法分别实现稀疏矩阵的乘法和加法
用十字链表和一般方法分别实现稀疏矩阵的乘法和加法

#include

#include

#define Size 2501

# define Size1 51

typedef struct

{

int i;

int j;

int e;//非零元的值

}triple; //定义三元组

typedef struct

{

triple data[Size+1];//矩阵中的元素

int rops[Size1+1];// rops[i]为第i行元素中的首非零元在data[]中的序号

int mu;//行数

int nu;//列数

int tu;//非零元数

} juzhen;//定义矩阵

typedef struct node// 定义十字链表元素

{

int i,j,e;

struct node *right,*down;// 该非零元所在行表和列表的后继元素

}node,*link;

typedef struct // 定义十字链表对象结构体

{

link *rhead,*chead;//行和列的头指针

int m,n,t;// 系数矩阵的行数,列数,和非零元素个数

}crosslist;

void createcross(crosslist &M)//建立十字链表

{

int i,j,e,k;

node *p,*q;

printf("输入行,列和非零元数,空格隔开:\n");

scanf("%d %d %d",&M.m,&M.n,&M.t);

M.rhead=(link *)malloc((M.m+1)*sizeof(link));//给行和列的头指针分配内存M.chead=(link *)malloc((M.n+1)*sizeof(link));

for(k=1;k<=M.m;k++)//初始化行,列的头指针

M.rhead[k]=NULL;

for(k=1;k<=M.n;k++)

M.chead[k]=NULL;

printf("输入非零元的行,列和值,空格隔开:\n");

for(k=1;k<=M.t;k++)//输入非零元

{

scanf("%d %d %d",&i,&j,&e);

p=(node *)malloc(sizeof(node));

p->i=i;

p->j=j;

p->e=e;

if(M.rhead[i]==NULL||M.rhead[i]->j>j)//插入元素所在行无非零元或首非零元的列标大于插入元素的列标

{

p->right=M.rhead[i];

M.rhead[i]=p;

}

else

{

for(q=M.rhead[i];(q->right)&&q->right->jright);//空循环找到第一个列标大于或等于插入元素列标的元素

p->right=q->right;

q->right=p;

}

if(M.chead[j]==NULL||(M.chead[j]->i>i))//插入元素所在列无非零元或首非零元的行标大于插入元素的行标

{

p->down=M.chead[j];

M.chead[j]=p;

}

else

{

for(q=M.chead[j];(q->down)&&q->down->idown);//空循环找到第一个行标大于或等于插入元素行标的元素

p->down=q->down;

q->down=p;

}

}

}

void printcross(crosslist A)//输出十字链表

{

if(A.m==0)

printf("十字链表为空!\n");

else

{

printf("十字链表为:\n");

int i,j;

for(i=1;i<=A.m;i++)

{

link p=A.rhead[i];

for(j=1;j<=A.n;j++)

{

if((p)&&(j==p->j))

{

printf("%5d",p->e);

p=p->right; }

else

printf("%5d",0);

}

printf("\n");

}

}

printf("\n");

}

crosslist addcross()

{

printf("十字链表加法:\n");

crosslist a,b;// 创建两个十字链表对象,并初始化

createcross(a);

createcross(b);

node *pre,*h[51],*pa,*pb,*q;//定义辅助指针,pa,pb分别为a,b当前比较的元素,pre为pa的前驱元素

int i,j,k=0,m,n; //h[j]指向j列的当前插入位置

if(a.m!=b.m||a.n!=b.n)

printf("格式不对,不能相加!\n");

else

{

for(i=1;i<=a.m;i++)

{

pa=a.rhead[i];

pb=b.rhead[i];

pre=NULL;

for(j=1;j<=a.n;j++)

h[j]=NULL;

while(pb)

{

p=(node *)malloc(sizeof(node)); // 开辟新节点,存储b中取出的元素

p->i=pb->i;

p->j=pb->j;

p->e=pb->e;

if(pa==NULL||pa->j>pb->j)//当a此行已经检查完或者pb因该放在pa前面

{

if (pre==NULL)

a. rhead[p->i]=p;

else

pre->right=p;

p->right=pa;

pre=p;

if (h[p->j]==NULL)//当前插入位置下面无非零元

//因为是逐行处理,so,h[p->j],依次下移

//因此每次都是指向插入的位置

{

a. chead [p->j]= p;

p->down = NULL;

}

else

{

p->down = h[p->j]->down;

h[p->j]->down = p;

}

h[p->j]=p;//*******h[p->j]下移指向下次插入的位置

pb=pb->right;//pb指向该行下个元素

}

else if((pa&&pa->jj))//只要移动pa的指针****先不加||(pb==NULL&&pa)

{

pre = pa;

h[pa->j]=pa;//移动h[],使其指向下次插入的位置

pa = pa->right;

}

else if(pa->j==pb->j)

{

pa->e+=pb->e;

if(pa->e)//不为零

{

pre=pa;

h[pa->j]=pa;

pb=pb->right;//加

else//pa->e为零,删除节点

{

if (pre ==NULL)

a.rhead [pa->i]=pa->right;

else

{

pre->right=pa->right;

}

p=pa;//p指向pa,用来在下面修改列指针

pa=pa->right;

if (h [p->j]==NULL)

a.chead [p->j]=p->down;

else

{

h[p->j]->down=p->down;

}

free(p);

pb=pb->right;

}

}

}

}

}

return a;

}

void multycross(crosslist &c)//十字链表乘法

{

node *p,*q,*u,*v,*p1,*p2;

crosslist a,b;

link *r;

int i,j,k,e;

printf("十字链表乘法:\n");

createcross(a);

createcross(b);

if(a.n!=b.m)

printf("格式错误,不能相乘!\n");

else

{

c.m=a.m;

c.n=b.n;

c.t=0;

c.rhead=(link *)malloc((a.m+1)*sizeof(link));//给行和列的头指针分配内存

c.chead=(link *)malloc((b.n+1)*sizeof(link));

for(k=1;k<=a.m;k++)//初始化行,列的头指针

c.rhead[k]=NULL;

for(k=1;k<=b.n;k++)

c.chead[k]=NULL;

r=(link *)malloc((b.n+1)*sizeof(link));

for(i=1;i<=a.m;i++)

{

u=(node *)malloc(sizeof(node));

u->e=0;

u->i=0;

u->j=0;

for(k=1;k<=b.n;k++)//初始化r[]

r[k]=u;

p1=p=a.rhead[i];

for(j=1;j<=b.n;j++)

{

p=p1;

q=b.chead[j];

v=(node *)malloc(sizeof(node));//初始化v,v为将插入c矩阵的元素

v->e=0;

v->i=i;

v->j=j;

while(p&&q)

{

if(p->j>q->i)

q=q->down;

else if(p->ji)

p=p->right;

else

{

v->e+=p->e*q->e;

p=p->right;

q=q->down;

}

}

if(v->e)//如果不为零,则插入c矩阵中

{

//同建立十字链表

if(c.rhead[i]==NULL||c.rhead[i]->j>j)//插入元素所在行无非零元或首

非零元的列标大于插入元素的列标

{

v->right=c.rhead[i];

c.rhead[i]=v;

}

else

{

for(p2=c.rhead[i];(p2->right)&&(p2->right->jright);//空循环找到第一个列标大于或等于插入元素列标的元素

v->right=p2->right;

p2->right=v;

}

if(c.chead[j]==NULL||c.chead[j]->i>i)//插入元素所在列无非零元或首非零元的行标大于插入元素的行标

{

v->down=c.chead[j];

c.chead[j]=v;

}

else

{

for(p2=c.chead[j];(p2->down)&&(p2->down->idown);//空循环找到第一个行标大于或等于插入元素行标的元素

v->down=p2->down;

p2->down=v;

}

}

}

}

}

}

void create(juzhen & M) //创建稀疏矩阵

{

int i,t=0;

printf("输入矩阵行数和列数and非零元的个数,以空格隔开:\n");

scanf("%d %d %d",&M.mu,&M.nu,&M.tu);

printf("输入矩阵非零元的行,列,和数值(中间空格隔开):\n");

for(i=1;i<=M.tu;i++)

scanf("%d %d %d",&M.data[i].i,&M.data[i].j,&M.data[i].e); //输入三元组的元素for(i=1;i<=Size1;i++)//初始化rops【】

M.rops[i]=0;

for(i=1,t=1;i<=M.mu;i++)//得到各行第一个元素的序号

{

M.rops[i]=t;

while(M.data[t].i<=i&&t<=M.tu)//遇到i行非零元,则t累加

t++;

}

}

void add(juzhen A,juzhen B,juzhen & C)//稀疏矩阵加法

{

int k=1,temp=0,k1=1, k2=1;//k1,k2,k分别控制A,B,C中非零元的序号变化

printf("稀疏矩阵加法:\n");

create(A);

create(B);

if(A.mu!=B.mu||A.nu!=B.nu)

printf("格式不对,不能相加!\n");

else

{

while(k1<=A.tu&&k2<=B.tu)//当A,B中的非零元都没用完

{

if(A.data[k1].i

C.data[k++]=A.data[k1++];

else if(A.data[k1].i>B.data[k2].i)//同上

C.data[k++]=B.data[k2++];

else//data[k1],data[k2]行标相同

{

if(A.data[k1].j>B.data[k2].j)//data[k1]列标大于data[k2]列标,则把data[k2]的值赋给data[k]

C.data[k++]=B.data[k2++];

else if(A.data[k1].j

C.data[k++]=A.data[k1++];

else //行,列标都相同

{

temp=0;

temp=A.data[k1].e+B.data[k2].e;

if(temp)//相加后不为零

{

C.data[k].i=A.data[k1].i;

C.data[k].j=A.data[k1].j;

C.data[k].e=temp;

k++;

}

k1++;

k2++;

}

}

}

while(k1<=A.tu)//B中非零元已用完,A中还有非零元

C.data[k++]=A.data[k1++];

while(k2<=B.tu)//A中非零元已用完,B中还有非零元

C.data[k++]=B.data[k2++];

C.mu=A.mu;//确定C的行列数和非零元个数

C.nu=A.nu;

C.tu=k-1;

}

}

void print(juzhen A)//输出稀疏矩阵

{

printf("\n矩阵为:\n");

int i,j,k=1;

if(A.mu==0)

printf("矩阵为空!\n");

else if(A.tu==0)//矩阵元素为空

printf("零矩阵!\n");

else

for(i=1;i<=A.mu;i++)//逐行输出

{

for(j=1;j<=A.nu;j++)

{

if(A.data[k].i==i&&A.data[k].j==j)//行和列分别对应相等则输出相应非零元,否则输出零

printf("%5d",A.data[k++].e);

else

printf("%5d",0);

}

printf("\n");//该行输出结束,空行输出下一行

}

printf("\n");

}

void multy(juzhen A,juzhen B,juzhen &C)//稀疏矩阵乘法

{

int arow,brow,ccol,temp[51],p,q,t,tp,i;//各变量代表含义见下面

printf("稀疏矩阵乘法:\n");

create(A);

create(B);

if(A.nu!=B.mu)

printf("格式错误,不能相乘!\n");

else

{

C.mu=A.mu;//初始化c的行列及非零元个数

C.nu=B.nu;

C.tu=0;

if(A.nu!=B.mu)

printf("A,B格式不对不能相乘!\n");

else //

{

for(arow=1;arow<=A.mu;arow++)//arow为当前A矩阵的行标

{

for(i=0;i<51;i++)//初始化temp

temp[i]=0;

if(arow

tp=A.rops[arow+1];//tp为arow+1行的首非零元在data【】中的序号else //arow为最后一行

tp=A.tu+1;

for(p=A.rops[arow];p

{

brow=A.data[p].j;//brow为与B矩阵中的相应行对应的A中当前元素的列标

if(brow

t=B.rops[brow+1];//t为brow+1行的首非零元在B中data【】中的序号

else //brow大小等于B.mu

t=B.tu+1;

for(q=B.rops[brow];q

{

ccol=B.data[q].j;//ccol:data[p]*data[q]所得结果所在的列

temp[ccol]+=A.data[p].e*B.data[q].e;//temp【ccol】:相乘所得的C 矩阵中第arow行cool列元素的值

}

}

for(ccol=1;ccol<=B.nu;ccol++)//

if(temp[ccol])//temp【ccol】不为零,则把值赋到c中,c.tu加1。

{

C.data[++C.tu].e=temp[ccol];

C.data[C.tu].i=arow;

C.data[C.tu].j=ccol;

}

}

}

}

}

void clear(juzhen & A)//清空稀疏矩阵

{

int i;

A.mu=0;

A.nu=0;

A.tu=0;

for(i=0;i

A.rops[i]=0;

for(i=0;i

{

A.data[i].i=0;

A.data[i].j=0;

A.data[i].e=0;

}

}

void main()

{

juzhen A,B,C,D;

crosslist a,b,c,d;

lable:

printf("******************************************************************\n");

printf("请选择:1、稀疏矩阵的加法,并输出结果,2、稀疏矩阵乘法,并输出结果\n");

printf("\n3、十字链表加法,并输出,4、十字链表乘法并输出,5、结束:\n");

printf("******************************************************************\n");

int x;

scanf("%d",&x);

switch(x)

{

case 1:

add(A,B,C);

print(C);

printf("\n");

goto lable;

case 2:

multy(A,B,C);

print(C);

printf("\n");

goto lable;

case 3:

a=addcross();

printcross(a);

printf("\n");

goto lable;

case 4:

multycross(b);

printcross(b);

printf("\n");

goto lable;

case 5:

break;

}

printf("\n");

}

/*

乘法测试数据:

矩阵原型:

4 -3 0 0 1 3 0 0 24 -6 0 0 0 0 8 0 * -4 2 0 8 0 0 0 0 1 0 0 0 1 0 = 0 1 0 0 0 0 0 70 1 0 0 0 0 0 0 0 0

4 5 6

1 1 4

1 2 -3

1 5 1

2 4 8

3 3 1

4 5 70

5 3 5

1 1 3

2 1 -4

2 2 2

3 2 1

4 1 1

4 5 20

1 1 1

1 2 1

1 3 1

1 4 1

1 5 1

2 1 1

2 2 1

2 3 1

2 4 1

2 5

1

3 1 1

3 2 1

3 3 1

3 4 1

3 5 1

4 1 1

4 2 1

4 3 1

4 4 1

4 5 1

5 3 15

1 1 -2

1 2 -2

1 3 -2

2 1 -2

2 2 -2

2 3 -2

3 1 -2

3 2 -2

3 3 -2

4 1 -2

4 2 -2

4 3 -2

5 1 -2

5 2 -2

5 3 -2

矩阵加法:

原型:

4 0 0 -8 0 0 0 0 1 4 0 -7

0 0 9 0 0 1 10 0 8 -6 0 0

0 -3 7 6 0 -2 + 1 0 0 0 0 0 =

1 5 0 0 0 0 0 3 0 0 0 0

-4 0 0 -2 0 9 0 0 0 -1 0 0

4 0 1 -4 0 -7

10 0 17 -6 0 1

1 -3 7 6 0 -2

1 8 0 0 0 0

-4 0 0 -3 0 9

5 6 13

1 1 4

1 4 -8

2 3 9

2 6 1

3 2 -3

3 3 7

3 4 6

3 6 -2

4 1 1

4 2 5

5 1 -4

5 4 -2

5 6 9

5 6 9

1 3 1

1 4 4

1 6 -7

2 1 10

2 3 8

2 4 -6

3 1 1

4 2 3

5 4 -1

*/

一、需求分析

1、分别用一般方法和和十字链表法,存储稀疏矩阵,并实现矩阵的加法和乘法

运算。用一般方法时,用M..rops[i]保存矩阵M中第i行的首非零元在矩阵

所有非零元中的顺序,并用M.data[]保存矩阵M的非零元,矩阵最多有2500个非零元,最大有50行。用十字链表法时,用right和down分别指示非零元的行后继和列后继元素,rhead和chead分别指向行表和列表的头,头结点都没有用到。

2、演示程序程序以用户和计算机的对话方式进行,即在计算机终端上显示提示

信息之后,由用户在键盘上输入演示程序中规定的运算命令;相应的输入数据和运算结果显示在其后。

3、程序执行的命令包括:

请选择:1、稀疏矩阵的加法,并输出结果,2、稀疏矩阵乘法,并输出结果

十字链表加法,并输出,4、十字链表乘法并输出,5、结束:

4、测试数据

(1)、乘法

矩阵原型:

4 -3 0 0 1 3 0 0 24 -6 0

0 0 0 8 0 * -4 2 0 8 0 0

0 0 1 0 0 0 1 0 = 0 1 0

0 0 0 0 70 1 0 0 0 0 0

4 5 6

1 1 4

1 2 -3

1 5 1

2 4 8

3 3 1

4 5 70

5 3 5

1 1 3

2 1 -4

2 2 2

3 2 1

4 1 1

(2)、加法

矩阵原型:

4 0 0 -8 0 0 0 0 1 4 0 -7

0 0 9 0 0 1 10 0 8 -6 0 0

0 -3 7 6 0 -2 + 1 0 0 0 0 0 =

1 5 0 0 0 0 0 3 0 0 0 0

-4 0 0 -2 0 9 0 0 0 -1 0 0

4 0 1 -4 0 -7

10 0 17 -6 0 1

1 -3 7 6 0 -2

1 8 0 0 0 0

-4 0 0 -3 0 9

5 6 13

1 1 4

1 4 -8

2 3 9

2 6 1

3 2 -3

3 3 7

3 4 6

3 6 -2

4 1 1

4 2 5

5 1 -4

5 4 -2

5 6 9

5 6 9

1 3 1

1 4 4

1 6 -7

2 1 10

2 3 8

2 4 -6

3 1 1

4 2 3

5 4 -1

二、概要设计

1.稀疏矩阵的抽象数据类型定义为:

ADT juzhen

{

数据对象:D={ m,n,t,data |m,n,t,data 属于 Elemset} 数据关系:R={}

基本操作:

Create(juzhen M)

操作结果:构造了矩阵M。

Add(juzhen A,juzhen B,juzhen &C)

初始条件:矩阵A,B已存在。

操作结果:使A,B矩阵相加并把结果赋到C矩阵。

Multy(juzhen A,juzhen B,juzhen &C)

初始条件:矩阵A,B已存在。

操作结果:使A,B矩阵相乘并把结果赋到C矩阵。

Print(juzhen A)

初始条件:矩阵A已存在。

操作结果:输出稀疏矩阵A。

}ADT juzhen

2、十字链表的抽象数据类型定义为:

ADT crosslist

{

数据对象:{rhead,chead,m,n,t | rhead,chead,m,n,t 属于Elementset} 数据关系:R1={}

基本操作:

Createcross(crosslist &M)

创建十字链表矩阵M。

Addcross()

操作结果:创建两个十字链表a,b,使a+b的值赋给a,并返回a。Multycross(crosslist &c)

操作结果:创建两个十字链表a,b,使a*b的值赋给c。

Printcross(crosslist A)

初始条件:矩阵A已经存在。

操作结果:输出十字链表。

}ADT crosslist

3、本程序包括三个模块

(1)、主程序模块

Void main()

{

Switch()

{

}

}

(2)、稀疏矩阵模块----实现稀疏矩阵的加法,乘法,及输出操作

(3)、十字链表模块----实现稀疏矩阵的加法,乘法,及输出操作

三、详细设计

1、三元组类型

typedef struct

{

int i;

int j;

int e;//非零元的值

}triple; //定义三元组

2、稀疏矩阵类型

typedef struct

{

triple data[Size+1];//矩阵中的元素

int rops[Size1+1];// rops[i]为第i行元素中的首非零元在data[]中的序号

int mu;//行数

int nu;//列数

int tu;//非零元数

} juzhen;//定义矩阵

3、结点类型

typedef struct node

{

int i,j,e;

struct node *right,*down;// 该非零元所在行表和列表的后继元素

}node,*link;

4、十字链表类型

typedef struct // 定义十字链表对象结构体

{

link *rhead,*chead;//行和列的头指针

int m,n,t;// 系数矩阵的行数,列数,和非零元素个数

}crosslist;

其中部分操作的算法:

void printcross(crosslist A)//输出十字链表

{

printf("十字链表为:\n");

int i,j;

for(i=1;i<=A.m;i++)

{

link p=A.rhead[i];

for(j=1;j<=A.n;j++)

{

if((p)&&(j==p->j))

{

printf("%5d",p->e);

p=p->right; }

else

printf("%5d",0);

}

printf("\n");

}

printf("\n");

}

crosslist addcross()

{

printf("十字链表加法:\n");

crosslist a,b;// 创建两个十字链表对象,并初始化

createcross(a);

createcross(b);

node *pre,*h[51],*pa,*pb,*q;//定义辅助指针,pa,pb分别为a,b当前比较的元素,pre为pa的前驱元素

int i,j,k=0,m,n; //h[j]指向j列的当前插入位置

if(a.m!=b.m||a.n!=b.n)

printf("格式不对,不能相加!\n");

else

{

for(i=1;i<=a.m;i++)

{

pa=a.rhead[i];

pb=b.rhead[i];

pre=NULL;

for(j=1;j<=a.n;j++)

h[j]=NULL;

while(pb)

{

link p;

p=(node *)malloc(sizeof(node)); // 开辟新节点,存储b中取出的元素

p->i=pb->i;

p->j=pb->j;

p->e=pb->e;

if(pa==NULL||pa->j>pb->j)//当a此行已经检查完或者pb因该放在pa前面

{

if (pre==NULL)

a. rhead [p->i]=p;

else

pre->right=p;

p->right=pa;

pre = p;

if (h[p->j]==NULL)//当前插入位置下面无非零元

//因为是逐行处理,so,h[p->j],依次下移

//因此每次都是指向插入的位置

{

a. chead [p->j]= p;

p->down = NULL;

}

else

{

p->down = h[p->j]->down;

h[p->j]->down = p;

}

h[p->j]=p;//*******h[p->j]下移指向下次插入的位置

pb=pb->right;//pb指向该行下个元素

}

else if((pa&&pa->jj))//只要移动pa的指针****先不加||(pb==NULL&&pa)

{

pre = pa;

h[pa->j]=pa;//移动h[],使其指向下次插入的位置

pa = pa->right;

}

else if(pa->j==pb->j)

{

pa->e+=pb->e;

if(pa->e)//不为零

{

pre=pa;

h[pa->j]=pa;

pb=pb->right;//加

}

else//pa->e为零,删除节点

{

if (pre ==NULL)

a.rhead [pa->i]=pa->right;

else

{

pre->right=pa->right;

}

p=pa;//p指向pa,用来在下面修改列指针

pa=pa->right;

if (h [p->j]==NULL)

a.chead [p->j]=p->down;

else

{

h[p->j]->down=p->down;

}

free(p);

pb=pb->right;

实现稀疏矩阵(采用三元组表示)的基本运算实验报告

实现稀疏矩阵(采用三元组表示)的基本运算实验报告 一实验题目: 实现稀疏矩阵(采用三元组表示)的基本运算二实验要求: (1)生成如下两个稀疏矩阵的三元组 a 和 b;(上机实验指导 P92 )(2)输出 a 转置矩阵的三元组; (3)输出a + b 的三元组; (4)输出 a * b 的三元组; 三实验内容: 稀疏矩阵的抽象数据类型: ADT SparseMatrix { 数据对象:D={aij| i = 1,2,3,….,m; j =1,2,3,……,n; ai,j∈ElemSet,m和n分别称为矩阵的行数和列数} 数据关系: R={ Row , Col } Row ={ | 1≤i≤m , 1≤j ≤n-1} Col ={| 1≤i≤m-1,1≤j ≤n} 基本操作:

CreateSMatrix(&M) 操作结果:创建稀疏矩阵 M PrintSMatrix(M) 初始条件:稀疏矩阵M已经存在 操作结果:打印矩阵M DestroySMatrix(&M) 初始条件:稀疏矩阵M已经存在 操作结果:销毁矩阵M CopySMatrix(M, &T) 初始条件:稀疏矩阵M已经存在 操作结果:复制矩阵M到T AddSMatrix(M, N, &Q) 初始条件:稀疏矩阵M、N已经存在 操作结果:求矩阵的和Q=M+N SubSMatrix(M, N, &Q) 初始条件:稀疏矩阵M、N已经存在 操作结果:求矩阵的差Q=M-N TransposeSMatrix(M, & T) 初始条件:稀疏矩阵M已经存在 操作结果:求矩阵M的转置T MultSMatrix(M, N, &Q) 初始条件:稀疏矩阵M已经存在

采用十字链表表示稀疏矩阵,并实现矩阵的加法运算

课程设计 所抽题目:采用十字链表表示稀疏矩阵,并实现矩阵的加法运算。 要求:要检查有关运算的条件,并对错误的条件产生 报警。 问题分析和建立模型:本题目主要是运用所学知识,用十字链表的方法去表示稀疏矩阵,并使之可以在两矩阵间进行相加。而后,若有错误,则对错误进行警报。 框架搭建: 1选择File|New菜单项,弹出New对话框,选择Files标签,选中C++ Source File项,在File编辑器中输入项目名称“十字链表表示稀疏矩阵实现加法”,在Location编辑框中输入项目所在目录,按下OK 按钮即可。 2在操作界面中输入,程序代码。 (1)结构体和共用体的定义 #include #include #define smax 45 typedef int datatype; typedef struct lnode (2)建立稀疏矩阵的函数,返回十字链表头指针 int i,j; struct lnode *cptr,*rptr; union {

struct lnode *next; datatype v; }uval; }link; int flag=0; 建立十字链表头结点 head=(link *)malloc(sizeof(link)); 建立头结点循环链表 for(i=1;i<=s;i++) (3)插入结点函数 p=(link *)malloc(sizeof(link)); p->i=0;p->j=0; p->rptr=p;p->cptr=p; cp[i]=p; cp[i-1]->uval.next=p; } cp[s]->uval.next=head; for(k=1;k<=t;k++) { printf("\t 第%d个元素(行号i 列号j 值v,数字间用空格分隔):",k); scanf("%d%d%d",&i,&j,&v); p=(link *)malloc(sizeof(link)); p->i=i;p->j=j;p->uval.v=v; q=cp[i]; while((q->rptr!=cp[i])&&(q->rptr->jrptr; p->rptr=q->rptr; q->rptr=p; q=cp[j]; while((q->cptr!=cp[j])&&(q->cptr->icptr; p->cptr=q->cptr; q->cptr=p; } return head; (4)输出十字链表的函数 link *p,*q; p=(link *)malloc(sizeof(link)); p->i=i;p->j=j;p->uval.v=v; q=cp[i];

(完整版)十字相乘法练习题

十字相乘法习题 1.232++x x 2.562++x x 3.11122++x x 4.17182++x x 5.342++x x 6.342+-x x 7.322-+x x 8.322--x x 9.672+-x x 10.652--x x 11.62-+x x 12.62--x x 13.22625a a +- 14.2024--x x 15.8624++x x 16. 42718x x +- 17.2223y xy x +- 18. 22149b ab a +- 19.8722--ax x a 20.10322-+mn n m 21. 223613b yb y +- 22. 9102+--a a 23. a a a 12423+-- 24. 222265x y x y x -- 25. 3)(4)(2++-+x b a b a 26. 10)2(3)2(2-+++y x y x 27. 12)4(7)4(222++++x x x x 28.2224)3(x x -- 29.6)25)(35(22--+++x x x x 30.24)4)(3)(2)(1(++-+-x x x x

31. 223x x -- 32. 2257x x +- 33. 2321a a -- 34. 23145b b +- 35.22157x x ++ 36. 2384a a -+ 37. 2576x x +- 38. 261110y y -- 39.313122+-x x 40.272442++x x 41.8652-+x x 42.1322++x x 43.61362+-y y 44.6732--a a 45.15442-+n n 46.3562-+x x 47.13852--x x 48. 2152-+x x 49.220920y y -- 50.2252310a b ab +- 51. 222231710a b abxy x y -+ 52. 53251520x x y xy -- 53. 22122+-)(x x 54. 108)2(39)2(324+---y x y x 55.8306251022++-+-y x y xy x 54. 222210173b a abxy y x +- 55. 2222)332()123(++-++x x x x

数据结构三元组完成版

#include #include typedef int ElemType; // 稀疏矩阵的三元组顺序表存储表示 #define MAXSIZE 100 // 非零元个数的最大值 typedef struct { int i,j; // 行下标,列下标 ElemType e; // 非零元素值 }Triple; typedef struct { Triple data[MAXSIZE+1]; // 非零元三元组表,data[0]未用 int mu,nu,tu; // 矩阵的行数、列数和非零元个数 }TSMatrix; // 创建稀疏矩阵M int CreateSMatrix(TSMatrix *M) { int i,m,n; ElemType e; int k; printf("请输入矩阵的行数,列数,非零元素个数:(逗号)\n"); 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),元素值:(逗号)\n", 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 1; } // 销毁稀疏矩阵M,所有元素置空 void DestroySMatrix(TSMatrix *M) { (*M).mu=0; (*M).nu=0; (*M).tu=0; } // 输出稀疏矩阵M void PrintSMatrix(TSMatrix M) { int i; printf("\n%d行%d列%d个非零元素。\n",M.mu,M.nu,M.tu); printf("%4s%4s%8s\n", "行", "列", "元素值"); for(i=1;i<=M.tu;i++) printf("%4d%4d%8d\n",M.data[i].i,M.data[i].j,M.data[i].e); } // 由稀疏矩阵M复制得到T int CopySMatrix(TSMatrix M,TSMatrix *T) { (*T)=M; return 1; } // AddSMatrix函数要用到 int comp(int c1,int c2) { int i; if(c1

稀疏矩阵的运算(完美版)

专业课程设计I报告(2011 / 2012 学年第二学期) 题目稀疏矩阵的转换 专业软件工程 学生姓名张鹏宇 班级学号 09003018 指导教师张卫丰 指导单位计算机学院软件工程系 日期 2012年6月18号

指导教师成绩评定表

附件: 稀疏矩阵的转换 一、课题内容和要求 1.问题描述 设计程序用十字链表实现稀疏矩阵的加、减、乘、转置。 2.需求分析 (1)设计函数建立稀疏矩阵,初始化值。 (2)设计函数输出稀疏矩阵的值。 (3)构造函数进行两个稀疏矩阵相加,输出最终的稀疏矩阵。 (4)构造函数进行两个稀疏矩阵相减,输出最终的稀疏矩阵。 (5)构造函数进行两个稀疏矩阵的相乘,输出最终的稀疏矩阵。 (6)构造函数进行稀疏矩阵的转置,并输出结果。 (7)退出系统。 二、设计思路分析 (1)设计函数建立稀疏矩阵,初始化值。 (2)设计函数输出稀疏矩阵的值。 (3)构造函数进行两个稀疏矩阵相加,输出最终的稀疏矩阵。 (4)构造函数进行两个稀疏矩阵相减,输出最终的稀疏矩阵。 (5)构造函数进行两个稀疏矩阵的相乘,输出最终的稀疏矩阵。 (6)构造函数进行稀疏矩阵的转置,并输出结果。 (7)退出系统。 三、概要设计 为了实现以上功能,可以从3个方面着手设计。 1.主界面设计 为了实现对稀疏矩阵的多种算法功能的管理,首先设计一个含有多个菜单项的主

控菜单子程序以链接系统的各项子功能,方便用户交互式使用本系统。本系统主控菜单运行界面如图所示。 2.存储结构设计 本系统采用单链表结构存储稀疏矩阵的具体信息。其中:全部结点的信息用头结点为指针数组的单链表存储。 3.系统功能设计 本系统除了要完成稀疏矩阵的初始化功能外还设置了4个子功能菜单。稀疏矩阵的初始化由函数i typedef int ElemType 实现。建立稀疏矩阵用void Creat()实现,依据读入的行数和列数以及非零元素的个数,分别设定每个非零元素的信息。4个子功能的设计描述如下。 (1)稀疏矩阵的加法: 此功能由函数void Xiangjia( )实现,当用户选择该功能,系统即提示用户初始化要进行加法的两个矩阵的信息。然后进行加法,最后输出结果。 (2)稀疏矩阵的乘法: 此功能由函数void Xiangcheng( )实现。当用户选择该功能,系统提示输

初中数学十字相乘法练习(20200710023442)

第十一讲 十字相乘法探究解决: (1)请直接填写下列结果 (x+2)(x+1)= ;(x+2)(x-1)= ;(x-2)(x+1)= ;(x-2)(x-1)= 。把上述式子左右对调,你有什么发现? 二次项系数为1的二次三项式 直接利用公式——))(()(2q x p x pq x q p x 进行分解。 特点:(1)二次项系数是1; (2)常数项是两个数的乘积; (3)一次项系数是常数项的两因数的和。 (4)归纳: ab x b a x )(2()()将x 2+3x+2分解因式,看下图,你有什么启发? x 2 +3x +2 2x + x = 3x 例 x 2 + 6x – 7= (x+7)(x-1) 步骤: ①竖分二次项与常数项 ②交叉相乘,和相加 ③检验确定,横写因式-x + 7x = 6x 例1. 用十字相乘法分解因式: (1)x 2-8x+15 (2)x 2+4x+3 (3)-x 2 -6x+16 练习 1.把下列各式分解因式: (1)1522x x = ; (2) 1032x x 。(3) x 2-2x-3= 。2.若6 52m m (m +a )(m +b ),则a 和b 的值分别是或。3. 分解因式(1)24142x x (2)36152a a (3)5 42x x (4)22x x (5)1522y y (6) 24 102x x x x 12 x 7x 1

例2.已知,如图,现有a a 、b b 的正方形纸片和a b 的矩形纸片各若干块,试选用这些纸片(每种纸片至 少用一次)在下面的虚线方框中拼成一个矩形(每两个纸片之间既不重叠,也无空隙,拼出的图中必须保留拼图的痕迹),使拼出的矩形面积为22 252a ab b ,并标出此矩形的长和宽。反馈练习 1.若652m m (m +a )(m +b ),则a 和b 的值分别是或. 2.3522x x (x -3) (__________).3.如图,正方形卡片 A 类、 B 类和长方形卡片 C 类各若干张,如果要拼一个长为(a +2b)、宽为(a +b)的大长方形, 则需要C 类卡片张.4.分解因式: (1)22157x x ; (2) 2384a a ;(3)15 22x x (4) 2576x x (5) 261110y y (6)10 32x x 5.先阅读学习,再求解问题: A a a B b b C b a 第3题图

稀疏矩阵的十字链表加法

目录 前言 (1) 正文 (1) 1.课程设计的目的和任务 (1) 2.课程设计报告的要求 (1) 3.课程设计的内容 (2) 4.稀疏矩阵的十字链表存储 (2) 5.稀疏矩阵的加法思想 (4) 6.代码实现 (5) 7.算法实现 (5) 结论 (8) 参考文献 (9) 附录 (10)

前言 采用三元组顺序表存储稀疏矩阵,对于矩阵的加法、乘法等操作,非零元素的插入和删除将会产生大量的数据移动,这时顺序存储方法就十分不便。稀疏矩阵的链接存储结构称为十字链表,它具备链接存储的特点,因此,在非零元素的个数及位置都会发生变化的情况下,采用链式存储结构表示三元组的线性更为恰当。 正文 1.课程设计的目的和任务 (1) 使我我们进一步理解和掌握所学的程序的基本结构。 (2) 使我们初步掌握软件开发过程的各个方法和技能。 (3) 使我们参考有关资料,了解更多的程序设计知识。 (4) 使我们能进行一般软件开发,培养我们的能力并提高我们的知识。 2.课程设计报告的要求 (1)课程设计目的和任务,为了达到什么要求 (2)课程设计报告要求 (3)课程设计的内容,都包含了什么东西 (4)稀疏矩阵和十字链表的基本概念,稀疏矩阵是怎么用十字链表存储 (5)十字链表矩阵的加法 (6)代码实现 (7)算法检测

3.课程设计的内容 (1)根据所学知识并自主查找相关资料 (2)进行算法设计与分析 (3)代码实现,组建并运行结果查看是否正确 (4)书写课程设计说明书 4.稀疏矩阵的十字链表存储 稀疏矩阵是零元素居多的矩阵,对于稀疏矩阵,人们无法给出确切的概念,只要非零元素的个数远远小于矩阵元素的总数,就可认为该矩阵是稀疏的。 十字链表有一个头指针hm ,它指向的结点有五个域,如图1所示。row 域存放总行数m ,col 域存放总列数n ,down 和right 两个指针域空闲不用,next 指针指向第一个行列表头结点。 c o l r o w 图1 总表点结点 有S 个行列表头结点h[1],h[2],......h[s]。结点结构与总表头结点相同。Row 和col 域置0,next 指向下一行列表头结点,right 指向本行第一个非零元素结点,down 指向本列第一个非零元素结点如图2所示。当最后一个行列表头结点的next 域指向总表头结点的hm 时,就形成循环链表,见图4的第一行。

数据结构课程设计之稀疏矩阵实现与应用1

数据结构课程设计报告 题目:十字链表成为存储结构,实现稀疏矩阵的求和运算 学生姓名:张旋 班级:软件三班学号:201213040304 指导教师: 吴小平

一、需求分析 1.问题描述: 要求:十字链表下的稀疏矩阵的加、转、乘的实现。 2.基本功能 实现十字链表下的转置,乘法,加法运算。 3.输入输出 (1)设计函数建立稀疏矩阵,初始化值。 (2)设计函数输出稀疏矩阵的值。 (3)构造函数进行两个稀疏矩阵相加,输出最终的稀疏矩阵。 (4)构造函数进行两个稀疏矩阵的相乘,输出最终的稀疏矩阵。 (5)构造函数进行稀疏矩阵的转置,并输出结果。 (6)退出系统。 二、概要设计 1.设计思路: 本实验要求在三元组,十字链表下实现稀疏矩阵的加、转、乘。首先要进行矩阵的初始化操作,定义三元组和十字链表的元素对象。写出转置,加法,乘法的操作函数。通过主函数调用实现在一个程序下进行矩阵的运算操作。 2.数据结构设计: 抽象数据类型稀疏矩阵的定义如下: ADT SparseMatrix{ 数据对象:D={aij | i=1,2,…,m; j=1,2,..,n; aij∈Elemset, m和n分别称为矩阵的行数和列数。} 数据关系:R={Row,Col} Row={ | 1<=i<=m, 1<=j<=n-1} Col= { | 1<=i<=m-1, 1<=j<=n} 基本操作: CreateSMatrix(&M); 操作结果:创建稀疏矩阵M。 DestroySMatrix(&M); 初始条件:稀疏矩阵M存在。操作结果:销毁稀疏矩阵M。 PrintSMatrix(M); 初始条件:稀疏矩阵M存在。操作结果:输出稀疏矩阵M。 AddSMatrix(M,N,&Q); 初始条件:稀疏矩阵M与N的行数和列数对应相等操作结果:求稀疏矩阵的和Q=M+N。 MultSMatrix(M,N,&Q); 初始条件:稀疏矩阵M的列数等于N的行数。操作结果:求稀疏矩阵乘积Q=M*N。 TransposeSMatrix(M,&T); 初始条件:稀疏矩阵M存在。操作结果:求稀疏矩阵M的转置矩阵T。 }ADT SparseMatrix 3.软件结构设计:

三元组顺序表稀疏矩阵课程设计报告(不完整)

1.稀疏矩阵运算器

数据结构课程设计任务书 针对本课程设计,完成以下课程设计任务: 1、熟悉系统实现工具和上机环境。 2、根据课程设计任务,查阅相关资料。 3、针对所选课题完成以下工作: (1)需求分析 (2)概要分析 (3)详细设计 (4)编写源程序 (5)静态走查程序和上机调试程序 4、书写上述文档和撰写课程设计报告。

3.课程设计报告目录

4.正文 (1)问题描述 稀疏矩阵是指那些多数元素为零的矩阵。利用“稀疏”特点进行存储和计算可以大大节省存储空间,提高计算频率。实现一个能进行稀疏矩阵基本运算的运算器。 (2)需求分析 本课程设计的稀疏矩阵运算器在visual studio 2013下运行调试成功,可以实现的功能有: 1.矩阵运算方式选择 2.根据提示输入相应数据 3.显示最终结果 使用的主要存储结构为三元组,并用三元组形式进行运算。所有参与运算数据类型为整形,因此输入的数据应为整形数据。为了节省存储空间使用三元组数据进行运算,可以通过多次扫描三元组数据来实现,即使用嵌套循环函数。输出结果为通常的阵列形式,因此使用了右对齐,保证输出形式的整齐。 (3)概要分析 本次课程设计中定义的结构体 typedef struct { int i, j;//矩阵元素所在行列 int v;//元素的值 }triple; typedef struct { triple data[MAXSIZE]; triple cop[MAXSIZE];//辅助数组 int m, n, t;//矩阵的行列数 }tripletable; Main函数调用子函数时输入1为调用 int Push_juzhen(int m, int n, int count)函数,可以实现矩阵相加功能 输入2为调用 int Dec_juzhen(int m, int n, int count)函数,可实现矩阵相减功能 输入3为调用 int Mul_juzhen()函数,可以实现矩阵相乘功能 (4)详细分析(流程图伪代码) 加法函数 int Push_juzhen(int m, int n, int count)//矩阵相加(行,列,矩阵数) { // p行,q列,s非零元素个数,v元素值 //ucount对数组下标计数的变量,与变量x实现多个矩阵相加 for (int c = 0; c < count; c++) { int x = 0; cout << "请输入第" << c + 1 << "个矩阵的非零元素个数" << endl; cin >> s; cout << "请依次输入非零元素所在行和列以及该非零元素的值并以空格隔开" << endl; for (; x< s; x++)//传递行列及元素值

2公式法,十字相乘法

一元二次解法:(1)公式法 【知识要点】 1.计算方法 一,先将方程变为标准形式)0(02 ≠=++a c bx ax ,确认a ,b ,c 。 如何变: ① 通过移项或通分(如例一,例二,例三)注意:尽量使a 为正整数,方便计算 ② 通过公式计算展开(如例四,例五) 注意:符号 ③ 通过待定系数法结合①②(如例六) 注意:除了X ,其他均看做已知数 二,再计算△,当△=042≥-ac b ,有实数根。如△<0,则方程无解 三,根据求根公式,将a,b,c , △代入公式,即得:-=2b x a ±。 【典型例题】 领练:例一 例①4722=-x x 例② 02 122412=+-x x 例③05422=-+-x x 例④x x x x 6)1()12()12(2 2++=--+ 例⑤2(3)2(1)7x x x --+=- 例⑥())1(03212 ≠=+++-m m mx x m

测试:例二 1,x x 4212=- 2,11)2(5)31)(13(+-=-+x x x 3,(2)(3) 56x x --= 4,02222=-+-n m mx x 二,熟练掌握△,不解方程,能够判断方程根的情况。 方程有两个实数根→△≥0 方程有两个相等的实数根→△=0 方程有两个不相等的实数根→△>0 方程没有实数根→△<0 例三,变式训练 ①不解方程,请判别下列方程根的情况; (1)22340t t +-= ; (2) 2 16924x x += ; (3)25(1)70y y +-= ; ②方程242()0x a b x ab ---=的根的情况是 ; ③如果关于x 的方程222(41)210x k x k -++-=有两个不相等的实数根,那么k 的取值范 围是 . ④已知0,0,p q <<则一元二次方程20x px q ++=的根的情况是 ;

基于十字链表与三元组表的稀疏矩阵压缩存储实例研究

龙源期刊网 https://www.360docs.net/doc/8113801786.html, 基于十字链表与三元组表的稀疏矩阵压缩存储实例研究 作者:周张兰 来源:《软件导刊》2017年第11期 摘要:十字链表和带行链接信息的三元组表是稀疏矩阵的两种压缩存储方法。十字链表为链式存储结构,带行链接信息的三元组表为顺序存储结构。在MovieLens数据集上设计了分别采用十字链表和带行链接信息的三元组表对以用户为行、项目为列、用户评分为矩阵元的稀疏矩阵进行压缩存储,并在这两种存储结构上实现用户相似度计算算法。通过测试分析和比较了两种不同的压缩存储方法在创建及相似度计算上的执行效率,并探讨了各自的特点及适用条件。 关键词关键词:稀疏矩阵;十字链表;三元组表;压缩存储 DOIDOI:10.11907/rjdk.171845 中图分类号:TP302 文献标识码:A文章编号文章编号:16727800(2017)011002204 0引言 矩阵是科学与工程计算问题中研究的数学对象。在高阶矩阵中,可能存在很多相同值或零值的矩阵元,对这些矩阵元的存储造成存储空间的浪费。因此,可以对矩阵进行压缩存储,以节省存储空间,达到提高存储利用率的目的。在算法实现中,选择的存储结构不同,执行效率也将不同。对不同矩阵存储方法的特点进行分析和比较,有助于根据不同的实际应用,有针对性地选择更为合适的存储结构,以此提高矩阵运算及其它相关操作的运行效率。 1稀疏矩阵及存储 若一个m行n列矩阵中的零元素有t个,零元素个数t与矩阵元总数m×n的比值称为稀疏因子,一般认为若稀疏因子不大于0.05,则此矩阵为稀疏矩阵。设矩阵有10行10列,即总共100个元素,若其中零元素有95个,而非零元素仅有5个,则此矩阵为稀疏矩阵。在存储稀疏矩阵时,可以采用非压缩存储和压缩存储两种方式。非压缩存储使用二维数组,比如,设10 行10列的稀疏矩阵M的矩阵元均为整数,则可以使用二维数组存储该矩阵M,数组的定义用C语言[1]描述如下: int a[10][10];

稀疏矩阵的运算(完美版)

专业课程设计I报告( 2011 / 2012 学年第二学期) 题目稀疏矩阵的转换 专业软件工程 学生姓名张鹏宇 班级学号 09003018 指导教师张卫丰 指导单位计算机学院软件工程系 日期 2012年6月18号

指导教师成绩评定表

附件: 稀疏矩阵的转换 一、课题内容和要求 1.问题描述 设计程序用十字链表实现稀疏矩阵的加、减、乘、转置。 2.需求分析 (1)设计函数建立稀疏矩阵,初始化值。 (2)设计函数输出稀疏矩阵的值。 (3)构造函数进行两个稀疏矩阵相加,输出最终的稀疏矩阵。 (4)构造函数进行两个稀疏矩阵相减,输出最终的稀疏矩阵。 (5)构造函数进行两个稀疏矩阵的相乘,输出最终的稀疏矩阵。 (6)构造函数进行稀疏矩阵的转置,并输出结果。 (7)退出系统。 二、设计思路分析 (1)设计函数建立稀疏矩阵,初始化值。 (2)设计函数输出稀疏矩阵的值。 (3)构造函数进行两个稀疏矩阵相加,输出最终的稀疏矩阵。 (4)构造函数进行两个稀疏矩阵相减,输出最终的稀疏矩阵。 (5)构造函数进行两个稀疏矩阵的相乘,输出最终的稀疏矩阵。 (6)构造函数进行稀疏矩阵的转置,并输出结果。 (7)退出系统。 三、概要设计 为了实现以上功能,可以从3个方面着手设计。 1.主界面设计 为了实现对稀疏矩阵的多种算法功能的管理,首先设计一个含有多个菜单项的主控菜单子程序以链接系统的各项子功能,方便用户交互式使用本系统。本系统主控菜单运行界面如图所示。

2.存储结构设计 本系统采用单链表结构存储稀疏矩阵的具体信息。其中:全部结点的信息用头结点为指针数组的单链表存储。 3.系统功能设计 本系统除了要完成稀疏矩阵的初始化功能外还设置了4个子功能菜单。稀疏矩阵的初始化由函数i typedef int ElemType 实现。建立稀疏矩阵用void Creat()实现,依据读入的行数和列数以及非零元素的个数,分别设定每个非零元素的信息。4个子功能的设计描述如下。 (1)稀疏矩阵的加法: 此功能由函数void Xiangjia( )实现,当用户选择该功能,系统即提示用户初始化要进行加法的两个矩阵的信息。然后进行加法,最后输出结果。 (2)稀疏矩阵的乘法: 此功能由函数void Xiangcheng( )实现。当用户选择该功能,系统提示输入要进行相乘的两个矩阵的详细信息。然后进行相乘,最后得到结果。 (3)稀疏矩阵的转置: 此功能由函数void Zhuanzhi( )实现。当用户选择该功能,系统提示用户初始

稀疏矩阵乘法的运算

课程设计任务书 学生姓名:专业班级: 指导教师:夏红霞工作单位:计算机科学与技术学院题目: 稀疏矩阵乘法的运算 课程设计要求: 1、熟练掌握基本的数据结构; 2、熟练掌握各种算法; 3、运用高级语言编写质量高、风格好的应用程序。 课程设计任务: 1、系统应具备的功能: (1)设计稀疏矩阵的存储结构 (2)建立稀疏矩阵 (3)实现稀疏矩阵的乘法 2、数据结构设计; 3、主要算法设计; 4、编程及上机实现; 5、撰写课程设计报告,包括: (1)设计题目; (2)摘要和关键字; (3)正文,包括引言、需求分析、数据结构设计、算法设计、程序实现及测试、不足之处、设计体会等; (4)结束语; (5)参考文献。 时间安排:2010年7月5日-9日(第19周) 7月5日查阅资料 7月6日系统设计,数据结构设计,算法设计 7月7日 -8日编程并上机调试 7月9日撰写报告 7月10日验收程序,提交设计报告书。 指导教师签名: 2010年7月4日系主任(或责任教师)签名: 2010年7月4日

目录 1.摘要 (1) 2.关键字 (1) 3.引言 (1) 4. 问题描述 (1) 5. 系统设计 (1) 6. 数据结构 (3) 7. 算法描述 (3) 8. 测试结果与分析 (4) 9. 源代码 (12) 10. 总结 (29) 11.参考文献 (29)

稀疏矩阵乘法的运算 1.摘要:在一些数值计算中,一些二维矩阵的乘法运算很常见,我们经常采用线性代数中的知识进行运算,然而对一些含有非零元很少的二维矩阵也采用相同的方法时,就会发现那样的方法不仅需要很多的空间来存储0,造成空间复杂度比较大,而且算法的时间复杂度也较大。因此需要采取其他的方法来解决这个问题,由于0在乘法中其结果总是0,所以可以考虑采用三元组的方式去存储稀疏矩阵中的非零元,这样在计算过程中不仅需要的内存空间减少了,而且运算的速率也提高了。 2.关键字:稀疏矩阵乘法二维矩阵算法复杂度 3.引言:随着科学技术的发展,人们对矩阵的运算的几率越来越大,特别是高新科技研究中对矩阵的运算更是常见。但是如何高效的并占内存少的进行矩阵运算就是一个急需解决的问题。本文主要对稀疏矩阵的存储以及稀疏矩阵的乘法运算进行了研究和探讨。 4.问题描述:在一些数值计算中,一些二维矩阵的乘法运算很常见,我们经常采用线性代数中的知识进行运算,然而对一些含有非零元很少的二维矩阵也采用相同的方法时,就会发现那样的方法不仅需要很多的空间来存储0,造成空间复杂度比较大,而且算法的时间复杂度也较大。为了减少空间和时间复杂度,可以根据给定的二维数组的数据设计稀疏矩阵的存储结构,然后根据设计的稀疏矩阵存储结构建立一个稀疏矩阵,最后获得两个二维数组得到他们各自的稀疏矩阵,计算这两个稀疏矩阵的乘积。 5.系统设计: 5.1 设计目标:通过一定的数据结构,存储含有少量数据的矩阵,把他们存入一个稀疏矩阵中,然后实现稀疏矩阵的乘法运算。[基本要求]设计稀疏矩阵的存储结构;建立稀疏矩阵;实现稀疏矩阵的乘法

国家公务员行测:十字相乘法简介

公务员考试中的数学运算部分主要考察考生的算术式子的计算比较和数学应用题的分析运算能力。考生必须具备熟练的数学运算技能和扎实的数学基础知识,掌握一定的数学思想和方法,才能达到准确、迅速求解的要求。利用十字相乘法解公务员考试中的一些习题是很有效的。下面我们简单介绍一下这种方法,并结合例题分析。 十字相乘法的具体原理如下: 一个集合中的个体,可以有两个(或三个)不同的取值,一部分取值为A,另一部分的取值为B,平均值为C,求取值为A的个体与取值为B的个体的比例,假设A有X,B有(1-X)。 则 AX+B(1-X)=C X=(C-B)÷/(A-B) 1-X=(A-C)÷(A-B) 因此X :(1-X) = (C-B) :(A-C) 上面计算过程可抽象为 A C-B C B A-C 这就是十字相乘法,使用时要注意:1、用来解决两者之间的比例关系问题,2、得出的比例关系是基数的比例关系,3、总均值放中间,对角线上,大数减小数,结果放在对角线上。 例:某高校2006年度毕业学生7650名,比上年度增长2%,其中本科毕业生比上年度减少2%,而研究生毕业数量比上年度增加10%,那么,这所高校今年的本科生有()。 A 3920 B4410 C4900 D5490 解析:方法一:按照我们常规的思维方法,大家都能想到的是方程法,这样我们 设这所高校今年的本科生有x 人,则据题意可列如下方程: , 解得x= 4900. 我们看到题目的数字比较大,大家动笔计算起来很是复杂,这样虽然是算对了,但是会费很多的时间,这样在公务员考试有限的时间中,会给考生一些压力,并导致答不完题目。下面我们用上面介绍的十字相乘法解答,大家可以对照一下。 方法二:7650÷(1+2%)=7500,即2005年毕业生一共有7500人。

稀疏矩阵 引用 十字链表 运算

稀疏矩阵应用 摘要本课程设计主要实现在三元组存储结构与十字链表存储结构下输入稀疏矩阵,并对稀疏矩阵进行转置,相加,相乘操作,最后输出运算后的结果。在程序设计中,考虑到方法的难易程度,采用了先用三元组实现稀疏矩阵的输入,输出,及其转置,相加,相乘操作的方法,再在十字链表下实现。程序通过调试运行,结果与预期一样,初步实现了设计目标。 关键词程序设计;稀疏矩阵;三元组;十字链表 1 引言 ?课程设计任务 本课程设计主要实现在三元组存储结构与十字链表存储结构下输入稀疏矩阵,并对稀疏矩阵进行转置,相加,相乘操作,最后输出运算后的结果。稀疏矩阵采用三元组和十字链表表示,并在两种不同的存储结构下,求两个具有相同行列数的稀疏矩阵A和B的相加矩阵C,并输出C;求出A的转置矩阵D,输出D;求两个稀疏矩阵A和B的相乘矩阵E,并输出E。 ?课程设计性质 数据结构课程设计是重要地实践性教学环节。在进行了程序设计语言课和《数据结构》课程教学的基础上,设计实现相关的数据结构经典问题,有助于加深对数据结构课程的认识。本课程设计是数据结构中的一个关于稀疏矩阵的算法的实现,包括在三元组和十字链表下存储稀疏矩阵,并对输入的稀疏矩阵进行转置,相加,相乘等操作,最后把运算结果输出。此课程设计要求对数组存储结构和链表存储结构非常熟悉,并能熟练使用它们。

1.3课程设计目的 其目的是让我们在学习完C、数据结构等课程基础上,掌握多维数组的逻辑结构和存储结构、掌握稀疏矩阵的压缩存储及转置,相加,相乘等基本操作,并用不同的方法输出结果,进一步掌握设计、实现较大系统的完整过程,包括系统分析、编码设计、系统集成、以及调试分析,熟练掌握数据结构的选择、设计、实现以及操作方法,为进一步的应用开发打好基础。 需求分析 2.1设计函数建立稀疏矩阵及初始化值和输出稀疏矩阵的值 本模块要求设计函数建立稀疏矩阵并初始化,包括在三元组结构下和十字链表结构下。首先要定义两种不同的结构体类型,在创建稀疏矩阵时,需要设计两个不同的函数分别在三元组和十字链表下创建稀疏矩阵,在输入出现错误时,能够对错误进行判别处理,初始化稀疏矩阵都为空值,特别注意在十字链表下,对变量进行动态的地址分配。在设计输出稀疏矩阵的值的函数时,也要针对两种不同的情况,分别编制函数,才能准确的输出稀疏矩阵。在对稀疏矩阵进行初始化及输出值时,均只输出非零元素的值和它所在的所在行及所在列。 2.2构造函数进行稀疏矩阵的转置并输出结果 本模块要求设计函数进行稀疏矩阵的转置并输出转置后的结果,由于对稀疏函数的转置只对一个矩阵进行操作,所以实现起来难度不是很大,函数也比较容易编写。在编写函数时,要先定义一个相应的结构体变量用于存放转置后的矩阵,最后把此矩阵输出。 2.3构造函数进行两个稀疏矩阵相加及相乘并输出最终的稀疏矩阵 本模块要求设计相加和相乘函数对两个矩阵进行运算,并输出最终的稀疏矩阵,在进行运算前,要对两个矩阵进行检查,看是不是相同类型的矩阵,因为两个矩阵

数据结构稀疏矩阵基本运算实验报告

课程设计 课程:数据结构 题目:稀疏矩阵4 三元组单链表结构体(行数、列数、头) 矩阵运算重载运算符优 班级: 姓名: 学号: 设计时间:2010年1月17日——2010年5月XX日 成绩: 指导教师:楼建华

一、题目 二、概要设计 1.存储结构 typedef struct{ int row,col;//行,列 datatype v;//非0数值 }Node; typedef struct{ Node data[max];//稀疏矩阵 int m,n,t;//m 行,n 列,t 非0数个数 … … 2.基本操作 ⑴istream& operator >>(istream& input,Matrix *A)//输入 ⑵ostream& operator <<(ostream& output,Matrix *A){//输出 ⑶Matrix operator ~(Matrix a,Matrix b)//转置 ⑷Matrix operator +(Matrix a,Matrix b)//加法 ⑸Matrix operator -(Matrix a,Matrix b)//减法 ⑹Matrix operator *(Matrix a,Matrix b)//乘法 ⑺Matrix operator !(Matrix a,Matrix b)//求逆 三、详细设计 (1)存储要点 position[col]=position[col-1]+num[col-1]; 三元组表(row ,col ,v) 稀疏矩阵((行数m ,列数n ,非零元素个数t ),三元组,...,三元组) 1 2 3 4 max-1

稀疏矩阵乘法运算

稀疏矩阵的乘法运算 程序代码: #include #include #include #include #include #include #define Ture 1 #define Overflow -1 typedef struct OLnode { int i,j; int e; struct OLnode *right,*down; }OLnode,*Olink; typedef struct { Olink *rhead,*chead; int mu,nu,tu; }Crosslist; //在十字链表M.rhead[row]中插入一个t结点

void insert_row(Crosslist &M,OLnode *t,int row) { OLnode *p; int col=t->j; if(M.rhead[row]==NULL||M.rhead[row]->j>col) { t->right=M.rhead[row]; M.rhead[row]=t; } else { for(p=M.rhead[row];p->right&&p->right->jright);//寻找在行表中的插入位置 t->right=p->right; p->right=t; } } //在十字链表M.chead[col]中插入一个结点t void insert_col(Crosslist &M,OLnode *t,int col) { OLnode *p; int row=t->i; if(M.chead[col]==NULL||M.chead[col]->i>row) { t->down=M.chead[col];

稀疏矩阵应用.

稀疏矩阵应用 ●课题简介 1.1课题及要求 稀疏矩阵应用(限1 人完成) 设计要求:实现三元组,十字链表下的稀疏矩阵的加、转、乘的实现。 (1)稀疏矩阵的存储 (2)稀疏矩阵加法 (3)矩阵乘法 (4)矩阵转置 1.2课程任务分析 本课程设计主要实现在三元组存储结构与十字链表存储结构下输入稀疏矩阵,并对稀疏矩阵进行转置,相加,相乘操作,最后输出运算后的结果。稀疏矩阵采用三元组和十字链表表示,并在两种不同的存储结构下,求两个具有相同行列数的稀疏矩阵A和B的相加矩阵C,并输出C;求出A的转置矩阵D,输出D;求两个稀疏矩阵A和B的相乘矩阵E,并输出E。 1.3课程的意义 其意义是让我们在学习完C、数据结构等课程基础上,掌握多维数组的逻辑结构和存储结构、掌握稀疏矩阵的压缩存储及转置,相加,相乘等基本操作,并用不同的方法输出结果,进一步掌握设计、实现较大系统的完整过程,包括系统分析、编码设计、系统集成、以及调试分析,熟练掌握数据结构的选择、设计、实现以及操作方法,为进一步的应用开发打好基础。 ●程序分析 2.1设计函数建立稀疏矩阵及初始化值和输出稀疏矩阵的值 本模块要求设计函数建立稀疏矩阵并初始化,包括在三元组结构下和十字链表结构下。首先要定义两种不同的结构体类型,在创建稀疏矩阵时,需要设计两个不同的函数分别在三元组和十字链表下创建稀疏矩阵,在输入出现错误时,能够对错误进行判别处理,初始化稀疏矩阵都为空值,特别注意在十字链表下,对变量进行动态的地址分配。在设计输出稀疏矩阵的值的函数时,也要针对两种不同的情况,分别编制函数,才能准确的输出稀疏矩阵。在对稀疏矩阵进行初始化及输出值时,均只输出非零元素的值和它所在的所在行及所在列。 2.2构造函数进行稀疏矩阵的转置并输出结果 本模块要求设计函数进行稀疏矩阵的转置并输出转置后的结果,由于对稀疏函数的转置只对一个矩阵进行操作,所以实现起来难度不是很大,函数也比较容易编写。在编写函数时,要先定义一个相应的结构体变量用于存放转置后的矩阵,最后把此矩阵输出。

稀疏矩阵

攀枝花学院 学生课程设计(论文)课程名称 设计题目 学生姓名:学号: 所在院(系): 专业: 班级: 指导教师:职称: 年月日 攀枝花学院教务处制

注:任务书由指导教师填写。

课程设计(论文)指导教师成绩评定表

摘要 本课程设计主要实现在三元组存储结构与十字链表存储结构下输入稀疏矩阵,并对稀疏矩阵进行转置,相加,相乘等操作,最后输出运算后的结果。考虑到难易程度,先用三元组实现稀疏矩阵的输入,输出,及其转置,相加,相乘等操作的方法,再在十字链表下实现。程序通过调试运行,结果与预期一样,初步实现了设计目标。 关键词:程序设计,稀疏矩阵,三元组,十字链表

目录 摘要........................................................................ I 绪论 (1) 1.设计目的与要求 (2) 1.1题目名称:稀疏矩阵的操作 (2) 1.2设计要求 (2) 1.3设计涉及知识 (2) 2、功能设计 (2) 2.1需求分析 (2) 2.2总体设计 (3) 2.3数据结构 (3) 3.功能模块图 (3) 3.1概要设计 (4) 3.2 系统流程图 (5) 3.3 菜单函数 (6) 4.稀疏矩阵的操作的源代码及说明 (7) 4.1 矩阵的声明与结构体定义 (7) 4.2 矩阵的输出函数模块 (7) 4.3 两矩阵相加 (8) 4.4 矩阵的转置 (9) 4.5 创建矩阵 (10) 4.6 主函数模块 (12) 5程序运行结果 (13) 5.1 经过调试,无错误,无警告 (13) 5.2创建矩阵并显示登录页面即主菜单 (13) 5.3 运行操作 (14) 5.4转置矩阵A (14) 5.5转置矩阵B (15) 5.6输出矩阵R (15) 5.7退出程序 (15) 6编程中遇到的困难及解决方法 (16) 7总结心得及良好建议 (17) 8致谢 (18) 9参考文献 (19)

相关文档
最新文档