矩阵相加(十字链表)

描述
输入两个稀疏矩阵A和B,用十字链表实现A=A+B,输出它们相加的结果。
 
输入
第一行输入四个正整数,分别是两个矩阵的行m、列n、第一个矩阵的非零元素的个数t1和第二个矩阵的非零元素的个数t2,接下来的t1+t2行是三元组,分别是第一个矩阵的数据和第二个矩阵的数据, 三元组的第一个元素表示行,第二个元素表示列,第三个元素是该元素的值。
 
输出
输出相加后的矩阵三元组。
 
输入样例
3 4 3 2
1 1 1
1 3 1
2 2 2
1 2 1
2 2 3

 
输出样例
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;
}


  • 6
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值