c语言版数据结构(奇迹冬瓜)-数组和广义表(十字链表稀疏矩阵的加法)

/*
以下是用于测试的两个稀疏矩阵
   3  0  0  5                       
M= 0 -1  0  0  (M矩阵)            
   2  0  0  0

  -3  0  2  0                       
N= 0  5  0  0  (N矩阵)            
   0  0  0 -1      

M=M+N

   0  0  2  5                       
M= 0  4  0  0  (相加后的M矩阵)            
   2  0  0 -1      

以上是矩阵表示图

                 M.chead(colhead)           1          2         3        4
M.rhead(rowhead) 
1                                         1 1 3                         1 4 5(分别表示行列和该位置的值)

2                                                    2 2 -1

3                                         3 1 -2

                 N.chead(colhead)           1          2         3        4
N.rhead(rowhead) 
1                                         1 1 -3               1 3 2         

2                                                    2 2 5

3                                                                       3 4 -1           

M矩阵相加后
                 M.chead(colhead)           1          2         3        4
M.rhead(rowhead) 
1                                                              1 3 2    1 4 5    

2                                                    2 2 4

3                                         3 1 -2                        3 4 -1  

以上是三元表示形式 压缩的最后表现方式 忽略了矩阵中的零元
*/

#include<stdio.h>
#include<stdlib.h>
//宏定义

#define OK 1
#define ERROR 0
#define OVERFLOW -2


typedef int Status;
typedef struct OLNode               //替换一个结构体的名字
{
	int i,j,e;                      //矩阵三元组i代表行 j代表列 e代表当前位置的数据
	struct OLNode *right,*down;     //指针域 右指针 下指针
}OLNode,*OLink;                     //结构体的新名

typedef struct 
{
	OLink *rhead,*chead;            //行和列链表头指针由CreateSMatrix分配
	int mu,nu,tu;                   //稀疏矩阵的行数,列数和非零元的个数
}CrossList;

Status CreateMatrix_OL(CrossList *M);
Status AddSMatrix(CrossList *M,CrossList *N);


void main()
{
	CrossList M,N;
	int i;
	OLNode *p;
	printf("输入测试矩阵:\n");
	CreateMatrix_OL(&M);
	printf("输入测试矩阵:\n");
	CreateMatrix_OL(&N);
	AddSMatrix(&M,&N);
	printf("输出测试矩阵:\n");
	printf("M:\n---------------------\ni\tj\te\n---------------------\n");
	//printf("%d\n\n",M.rhead[2]->e);
	
	for (i=1;i<=M.nu;i++)
	{
		if (NULL!=M.chead[i])
		{
			p=M.chead[i];
			while (NULL!=p)
			{
				printf("%d\t%d\t%d\n",p->i,p->j,p->e);
				p=p->down;
			}
		}
	}
	getchar();
	getchar();
}

Status CreateMatrix_OL(CrossList *M)  //创建系数矩阵M,采用十字链表存储表示
{
     int m,n,t;      //定义矩阵的行,列,非零元的数量
     int i,j,e;      //定义中间变量
     OLNode *p,*q;       //定义中间变量  
   //  if(M)
     //{
       //  free(M);    //如果矩阵已经存在,那么释放矩阵
     //}
     scanf("%d%d%d",&m,&n,&t);  //输入矩阵的行列及非零元的数量
     M->mu=m;
     M->nu=n;
     M->tu=t;     //初始化矩阵的行列及非零元的数量
     if(!(M->rhead=(OLink*)malloc((m+1)*sizeof(OLink))))
     {
        exit(OVERFLOW);      //初始化矩阵的行链表            
     }
     if(!(M->chead=(OLink*)malloc((n+1)*sizeof(OLink))))
     {
         exit(OVERFLOW);     //初始化矩阵的列链表
     }
     for(i=1;i<=m;i++)
     {
         M->rhead[i]=NULL;   //初始化行
     }
     for(j=1;j<=n;j++)
     {
         M->chead[j]=NULL;   //初始化列
     }
     for(scanf("%d%d%d",&i,&j,&e);0!=i;scanf("%d%d%d",&i,&j,&e)) //输入三元组 直到行为0结束
     {
         if(!(p=(OLNode*)malloc(sizeof(OLNode))))
         {
             exit(OVERFLOW);                 //动态生成p
         }
         p->i=i;
         p->j=j;
         p->e=e;                             //初始化p
		 if(NULL==M->rhead[i]||M->rhead[i]->j>j)
		 {
			 p->right=M->rhead[i];
			 M->rhead[i]=p;
		 }
		 else
		 {
			 for(q=M->rhead[i];(q->right)&&q->j>j;q=q->right);
			 p->right=q->right;
			 q->right=p;
		 }                                          
		 if(NULL==M->chead[j]||M->chead[j]->i>i)
		 {
			 p->down=M->chead[j];
			 M->chead[j]=p;
		 }
		 else
		 {
			 for (q=M->chead[j];(q->down );q=q->down);
			 p->down=q->down;
			 q->down=p;
		 }
     }
	 return OK;
}

Status AddSMatrix(CrossList *M,CrossList *N)
{
	int i,j;
	OLNode *p,*q,*temp;
	if (M->mu!=N->mu||M->nu!=N->nu)
	{
		exit(OVERFLOW);
	}
	M->tu+=N->tu;
	for (i=1;i<=N->mu;i++)
	{
		p=N->rhead[i];
		while(NULL!=p)
		{
			if(NULL==M->rhead[p->i]||M->rhead[p->i]->j>p->j)
			{
				p->right=M->rhead[p->i];
				M->rhead[p->i]=p;
			}
			else if(M->rhead[p->i]->j<p->j)
			{
				for (q=M->rhead[p->i];(q->right)&&q->j<p->j;q=q->right);
				p->right=q->right;
				q->right=p;
			}
			if (NULL==M->chead[p->j]||M->chead[p->j]->i>p->i)
			{
				p->down=M->chead[p->j];
				M->chead[p->j]=p;
			}
			else if (M->chead[p->j]->i<p->i)
			{
				for (q=M->chead[p->j];(q->down)&&q->i<p->i;q=q->down);
				p->down=q->down;
				q->down=p;
			}
			else
			{
				M->chead[p->j]->e+=p->e;
				M->tu--;
				if (0==M->chead[p->j]->e)
				{
					M->tu--;
					M->chead[p->j]=M->chead[p->j]->down;
					M->rhead[p->i]=M->chead[p->j]->right;
				}
			}
			p=p->right;
		}
	}
	return OK;
}


 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值