您的位置:首页 > 其它

矩阵相加(十字链表)

2016-03-25 13:29 302 查看
[align=left]描述[/align]
输入两个稀疏矩阵A和B,用十字链表实现A=A+B,输出它们相加的结果。

[align=left]输入[/align]
第一行输入四个正整数,分别是两个矩阵的行m、列n、第一个矩阵的非零元素的个数t1和第二个矩阵的非零元素的个数t2,接下来的t1+t2行是三元组,分别是第一个矩阵的数据和第二个矩阵的数据, 三元组的第一个元素表示行,第二个元素表示列,第三个元素是该元素的值。

[align=left]输出[/align]
输出相加后的矩阵三元组。

[align=left]输入样例[/align]
3 4 3 2

1 1 1

1 3 1

2 2 2

1 2 1

2 2 3

[align=left]输出样例[/align]
1 1 1

1 2 1

1 3 1

2 2 5

#include <iostream>
#include <cstdio>
#include <cmath>
#include <stdlib.h>
#define ElemType int
using namespace std;

struct OLNode
{
int i, j;
ElemType elem;
struct OLNode *right, *down;
};
typedef struct OLNode OLNode, *OLink;

typedef struct
{
OLink*rHead, *cHead;
int mu, nu, tu;
}CrossList;

void CreateList(CrossList &M, int m, int n, int t)
{
M.mu = m, M.nu = n, M.tu = t;
M.rHead = (OLink*)malloc((M.mu+1)*sizeof(OLink));
M.cHead = (OLink*)malloc((M.nu+1)*sizeof(OLink));
int k = 0;
for(k = 1; k <= M.mu; k++)
M.rHead[k] = NULL;
for(k = 1; k <= M.nu; k++)
M.cHead[k] = NULL;
for(k = 1; k <= M.tu; k++)
{
int i, j, e;
scanf("%d %d %d", &i, &j, &e);
OLink q;
OLink p = (OLNode*)malloc(sizeof(OLNode));
p->i = i;
p->j = j;
p->elem = 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;
}
p->down = NULL;
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;
}
p->right = NULL;
}
}

void DestroyList(CrossList &M)
{
OLink p;
for(int k = 1; k <= M.mu; k++)
{
p = M.rHead[k];
while(p)
{
M.rHead[k] = p->right;
free(p);
p = M.rHead[k];
}
}
M.mu = 0;
M.nu = 0;
M.tu = 0;
}

void InsertNode(CrossList &M, OLink &p)
{
int i = p->i, j = p->j;
int deleted = 0, plused = 0;
if(M.rHead[i] == NULL)
{
M.rHead[i] = p;
M.tu++;
}
else
{
OLink q = M.rHead[i];
OLink pre = q;
while(q && (q->j < p->j))
{
pre = q;
q = q->right;
}
//对应结点相加
if(q!=NULL && q->j == p->j)
{
q->elem += p->elem;
if(q->elem == 0)
{
//第一个结点相加
if(pre == q)
M.rHead[i] = q->right;
else
pre->right = q->right;
M.tu--;
deleted = 1;
}
else
plused = 1;
}
//插入
if(!deleted && !plused)
//else
{
//插入作第一个结点
if(pre == q)
{
M.rHead[i] = p;
p->right = q;
}
else
{
pre->right = p;
p->right = q;
}
M.tu++;
}
}

if(M.cHead[j] == NULL)
M.cHead[j] = p;
else
{
OLink q = M.cHead[j];
OLink pre = q;
while(  q&&(q->i < p->i))
{
pre = q;
q = q->down;
}
if(deleted)
{
if(q!=NULL)
{
//头结点
if(pre == q)
M.cHead[j] = q->down;
else
pre->down = q->down;
free(q);
free(p);
return ;
}
}
if(!plused)
{
if(pre == q)
{
M.cHead[j] = p;
p->down = q;
}
else
{
pre->down = p;
p->down = q;
}
}
}

}

void AddList(CrossList &M, CrossList &N)
{
OLink p, q;
p = (OLNode*)malloc(sizeof(OLNode));
for(int k = 1; k <= N.mu; k++)
{
p = N.rHead[k];
while(p)
{
q = (OLNode*)malloc(sizeof(OLNode));
q->down = p->down;
q->right = p->right;
q->elem = p->elem;
q->i = p->i;
q->j = p->j;
//插入q,插入操作会更改结点p
InsertNode(M, q);
p = p->right;
}
}
}

void PrintList(CrossList &M)
{
//cout << " =========" << endl;
for(int k = 1; k <= M.mu; k++)
{
OLink p = M.rHead[k];
for(int t = 1; t <= M.nu; t++)
{
if(p && (t == p->j))
{
printf("%d %d %d\n", p->i, p->j, p->elem);
p = p->right;
}
}
}
//cout << endl;
}
int main()
{

int m, n, t1, t2;
scanf("%d %d %d %d", &m, &n, &t1, &t2);
CrossList A, B;
CreateList(A, m, n, t1);
//PrintList(A);
CreateList(B, m, n, t2);
//PrintList(B);
AddList(A, B);
PrintList(A);
//DestroyList(A);
//DestroyList(B);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: