#define OVERFLOW -1
//------------稀疏矩阵的十字链表存储表示--------------
typedef struct OLNode{
int
i,j; //该非零元的行和列下标
int
e; //非零元
struct OLNode * right, *
down; // right指向该非零元所在行的右边的非零元,down指向下面的非零元
}OLNode, * OLink;
typedef struct {
OLink * rhead, *
chead; //rhead指向一个一维数组,里面存放每个行链表的头结点;chead指向一个一维数组,里面存放每个列链表的头结点
int
mu,nu,tu; //稀疏矩阵的行数,列数,非零元个数
}CrossList;
#include "iostream"
#include "cstdio"
#include "cstdlib"
void CreateSMatrix_OL( CrossList &M )
{ //创建稀疏矩阵M;用十字链表存储
printf("----------请依次输入稀疏矩阵M的
行数、列数、非零元个数 (空格隔开)---------\n");
scanf("%d%d%d",&M.mu, &M.nu, &M.tu
); //输入M的行数、列数、非零元个数
if( !(M.rhead = (OLink *)malloc( (M.mu+1) *
sizeof(OLink)
)))
exit(OVERFLOW); //给rhead分配一个一维数组,失败则退出程序
if( !(M.chead = (OLink *)malloc( (M.nu+1) *
sizeof(OLink)
)))
exit(OVERFLOW); //给chead分配一个一维数组,失败则退出程序
int x;
for(x =1 ; x <= M.mu; x++) M.rhead[x] =
NULL; //初始化rhead指向的一维数组个元素都为空,即每个行链表都为空
for(x =1 ; x <= M.nu; x++) M.chead[x] =
NULL;
int i,j,e;
OLNode * p,* q;
int cnt_e;//用来统计非零元个数
printf("--------下面输入%d行,每行三个数:
行标 列标
元素的值(空格隔开)--------\n",M.mu);
for(cnt_e = 1; cnt_e <= M.tu ; cnt_e++){
scanf("%d%d%d",&i,&j,&e);
if( !(p = (OLNode
*)malloc(sizeof(OLNode) )))
exit(OVERFLOW); //分配一个临时结点,存放新接受的非零元
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->j < j); q =
q->right ) ;
//循环到合适位置,这是个空循环
p->right =
q->right; q->right =
p; //完成行插入
}//else
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->i < i); q =
q->down ) ; //循环到合适位置,这是个空循环
p->down =
q->down; q->down =
p; //完成列插入
}//else
}//for
return;
}
void PrintSMatrix_OL( CrossList M )
{
OLNode * pr;
int cnt_r,cnt_c;//控制行和列
printf("---------------------------- 稀疏矩阵
------------------------\n");
for( cnt_r =1; cnt_r <= M.mu; cnt_r++
){ //控制行
pr =
M.rhead[cnt_r]; //pr指向每一行的链表
for( cnt_c = 1; cnt_c<= M.nu
;cnt_c++){ //控制咧
if( NULL ==
pr ) printf("=
",0); //该行是空行
else
{//不是空行
if(cnt_c
== pr->j ) { printf("= ",pr->e); pr = pr->right;}
else
printf("= ",0);
}//else
//pr =
M.rhead[cnt_r];
}//for
printf("\n");
}//for
return;
}
void AddSMatrix_OL(CrossList M1,CrossList M2,CrossList
&M)
{
//创建空稀疏矩阵M
M.mu = M1.mu; M.nu =
M1.nu; M.tu = 0;
if( !(M.rhead = (OLink *)malloc( (M.mu+1) *
sizeof(OLink)
)))
exit(OVERFLOW); //给rhead分配一个一维数组,失败则退出程序
if( !(M.chead = (OLink *)malloc( (M.nu+1) *
sizeof(OLink)
)))
exit(OVERFLOW); //给chead分配一个一维数组,失败则退出程序
int x;
for( x =1 ; x <= M.mu; x++) M.rhead[x] =
NULL; //初始化rhead指向的一维数组个元素都为空,即每个行链表都为空
for( x =1 ; x <= M.nu; x++) M.chead[x] =
NULL;
//相加
int i,j,e,cnt_r;
OLNode * p1,*p2,*p,*q;
for( cnt_r=1; cnt_r<=M.mu; cnt_r++) //
按行的顺序相加
{
p1=M1.rhead[cnt_r];
// p1指向矩阵M1的第i行的第1个结点
p2=M2.rhead[cnt_r];
// p2指向矩阵N2的第i行的第1个结点
while(p1&&p2)
// p1和p2均不空
{
if(p1->j < p2->j) // 矩阵M当前结点的列小于矩阵N当前结点的列
{
if( !(p = (OLNode *)malloc(sizeof(OLNode) )))
exit(OVERFLOW); //分配一个临时结点,存放新接受的非零元
i = p1->i; j =
p1->j; e = p1->e;
p->i =
i;
p->j =
j;
p->e= e;// 给结点赋值
//p结点插入M
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->j < j);
q = q->right ) ;
//循环到合适位置,这是个空循环
p->right
= q->right; q->right =
p; //完成行插入
}//else
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->i < i); q
= q->down ) ; //循环到合适位置,这是个空循环
p->down
= q->down; q->down =
p; //完成列插入
}//else
M.tu++;
// 非零元素数加1
p1
= p1->right;
}
else if(p1->j > p2->j )// 矩阵M当前结点的列大于矩阵N当前结点的列
{
if( !(p = (OLNode *)malloc(sizeof(OLNode) )))
exit(OVERFLOW); //分配一个临时结点,存放新接受的非零元
i = p2->i; j =
p2->j; e = p2->e;
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->j < j);
q = q->right ) ;
//循环到合适位置,这是个空循环
p->right
= q->right; q->right =
p; //完成行插入
}//else
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->i < i); q
= q->down ) ; //循环到合适位置,这是个空循环
p->down
= q->down; q->down =
p; //完成列插入
}//else
M.tu++;
// 非零元素数加1
p2=p2->right; // p2指针向右移
}
else if(p1->e + p2->e) //
矩阵M、N当前结点的列相等且两元素之和不为0
{
if( !(p = (OLNode *)malloc(sizeof(OLNode) )))
exit(OVERFLOW); //分配一个临时结点,存放新接受的非零元
i = p1->i; j =
p1->j; e = p1->e
+p2->e;
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->j < j);
q = q->right ) ;
//循环到合适位置,这是个空循环
p->right
= q->right; q->right =
p; //完成行插入
}//else
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->i < i); q
= q->down ) ; //循环到合适位置,这是个空循环
p->down
= q->down; q->down =
p; //完成列插入
}//else
p1 = p1->right; // p1指针向右移
p2 = p2->right; // p2指针向右移
M.tu++; // 非零元素数加1
}
else {// 矩阵M、N当前结点的列相等且两元素之和为0
p1=p1->right; // p1指针向右移
p2=p2->right; // p2指针向右移
}
}//while
while(p1) //
将矩阵M该行的剩余元素插入矩阵Q
{
if( !(p = (OLNode *)malloc(sizeof(OLNode)
)))
exit(OVERFLOW); //分配一个临时结点,存放新接受的非零元
i = p1->i; j =
p1->j; e = p1->e ;
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->j < j);
q = q->right ) ;
//循环到合适位置,这是个空循环
p->right
= q->right; q->right =
p; //完成行插入
}//else
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->i < i); q
= q->down ) ; //循环到合适位置,这是个空循环
p->down
= q->down; q->down =
p; //完成列插入
}//else
p1 = p1->right; // p1指针向右移
M.tu++; //
非零元素数加1
}
while(p2) // 将矩阵N该行的剩余元素插入矩阵Q
{
if( !(p = (OLNode *)malloc(sizeof(OLNode) )))
exit(OVERFLOW); //分配一个临时结点,存放新接受的非零元
i = p2->i; j =
p2->j;
e = p2->e;
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->j < j);
q = q->right ) ;
//循环到合适位置,这是个空循环
p->right
= q->right; q->right =
p; //完成行插入
}//else
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->i < i); q
= q->down ) ; //循环到合适位置,这是个空循环
p->down
= q->down; q->down =
p; //完成列插入
}//else
p2=p2->right; // p1指针向右移
M.tu++; //
非零元素数加1
} //while
}//for
return;
}
int main ()
{
//freopen("Debug\\input.txt", "r", stdin);
// freopen("Debug\\output.txt", "w", stdout);
CrossList
M1,M2,M; //定义一个稀疏矩阵M
CreateSMatrix_OL(M1); //创建稀疏矩阵M;用十字链表存储
PrintSMatrix_OL(M1);
CreateSMatrix_OL(M2); //创建稀疏矩阵M;用十字链表存储
PrintSMatrix_OL(M2);
AddSMatrix_OL(M1,M2,M); // 稀疏矩阵M1,M2相加结果为M
PrintSMatrix_OL(M);
system("pause");
return 0;
}