以十字链表为存储结构实现矩阵相加(严5.27)--------西工大noj

 

#define  _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
typedef int ElemType;
typedef struct Node
{
    int row, col;
    ElemType data;
    struct Node* right, * down;
}Node;
typedef struct CrossLink
{
    Node* row_head;//注意:这是头结点数组
    Node* col_head;
    int row_max, col_max, size;
}CrossLink;
CrossLink* Creat(int m, int n)//创建
{
    CrossLink* C = (CrossLink*)malloc(sizeof(CrossLink));
    C->col_max = n;
    C->row_max = m;
    C->size = 0;
    C->row_head = (Node*)calloc(m + 1, sizeof(Node));
    C->col_head = (Node*)calloc(n + 1, sizeof(Node));//注意:指针是从1开始
    for (int i = 1; i <= m; i++)
    {
        (C->row_head[i]).right = NULL;
    }
    for (int i = 1; i <= n; i++)
    {
        (C->col_head[i]).down = NULL;
    }
    return C;
}
void Read(CrossLink* C, int n)
{
    for (int T = 0; T < n; T++)
    {
        int a, b, c;
        scanf("%d%d%d", &a, &b, &c);
        Node* left, * up;//注意:在遍历完成后,left指针和up指针指向目标节点的左边和上边
        left = &(C->row_head[a]);
        while (left->right && left->right->col <= b) left = left->right;
        up = &(C->col_head[b]);
        while (up->down && up->down->row <= a) up = up->down;
        Node* s = (Node*)malloc(sizeof(Node));
        s->data = c;
        s->row = a;
        s->col = b;
        s->down = up->down;
        up->down = s;
        s->right = left->right;
        left->right = s;
        C->size++;
    }
}
void Print(CrossLink* C)
{
    for (int i = 1; i <= C->row_max; i++)
    {
        Node* p = C->row_head[i].right;
        while (p)
        {
            printf("%d %d %d ", p->row, p->col, p->data);
            p = p->right;
            putchar('\n');
        }

    }
}
void Add(CrossLink* A, CrossLink* B)
{
    if (A->col_max != B->col_max || A->row_max != B->row_max)
        return;
    for (int i = 1; i <= A->row_max; i++)
    {
        Node* p = &(A->row_head[i]);
        Node* q = &(B->row_head[i]);
        while (p->right || q->right)
        {
            if (p->right && q->right && p->right->col == q->right->col)
            {
                int t = p->right->data + q->right->data;
                if (t == 0)
                {
                    Node* d = p->right;
                    p->right = p->right->right;
                    free(d);
                }
                else
                {
                    p->right->data = t;
                    p = p->right;
                }
                
                q = q->right;
            }
            else if (q->right == NULL || (p->right && p->right->col < q->right->col))
            {
                p = p->right;
            }
            else
            {
                Node* s = (Node*)malloc(sizeof(Node));
                s->col = q->right->col;
                s->data = q->right->data;
                s->row = q->right->row;
                s->right = p->right;
                p->right = s;
                {
                    Node* r = &(A->col_head[s->col]);
                    while (r->down && r->down->row <= r->row) r = r->down;
                    s->down = r->down;
                    r->down = s;
                }
                q = q->right;
            }

        }

    }
}
int main()
{
    int m, n;
    scanf("%d%d", &m, &n);
    CrossLink* A = Creat(m, n);
    CrossLink* B = Creat(m, n);
    int anum, bnum;
    scanf("%d%d", &anum, &bnum);
    Read(A, anum);
    Read(B, bnum);
    Add(A, B);
    Print(A);

}
/*
3 4 3 2
1 1 1
1 3 1
2 2 2
1 2 1
2 2 3
*/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值