稀疏矩阵的加法(用十字链表实现A=A+B)

描写叙述:

输入两个稀疏矩阵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 <stdio.h>
#include<stdlib.h>

typedef struct OLNODE
{
    int row,col;
    int data;
    struct OLNODE *right,*down;
} NODE,*LNODE;

typedef struct CORSS
{
    LNODE *rh,*ch;
    int ra,ca,da;
} CROSS, *LCROSS;

void Create(LCROSS A);

void PlusToA(LCROSS A,LCROSS B);

void PrintCross(LCROSS A);

int main()
{
    LCROSS A = (LCROSS)malloc(sizeof(CROSS));
    LCROSS B = (LCROSS)malloc(sizeof(CROSS));

    scanf("%d %d %d %d",&A->ra,&A->ca,&A->da,&B->da);
    B->ra = A->ra;
    B->ca = A->ca;

    Create(A);
    Create(B);//" 3  4 0 5  创建时B有问题"
    PlusToA(A,B);
    PrintCross(A);
    return 0;
}

void Create(LCROSS M)
{
    int i;
    LNODE p,temp;

    M->rh = (LNODE *)malloc((M->ra+1)*sizeof(LNODE));
    M->ch = (LNODE *)malloc((M->ca+1)*sizeof(LNODE));

    for(i=1; i<=M->ra; i++)
    {
        M->rh[i]=NULL;
    }
    /*for(i=1; i<=M->ca; i++)
    {
        M->ch[i]=NULL;
    }*/

    if(M->da != 0)
    {
        for(i=1; i<=M->da; i++)
        {
            p=(LNODE)malloc(sizeof(NODE));
            scanf("%d %d %d",&p->row,&p->col,&p->data);
            if(M->rh[p->row] == NULL)
            {
                p->right=NULL;
                M->rh[p->row] = p;

            }
            else
            {
                for(temp=M->rh[p->row];; temp=temp->right)
                {
                    if(temp->right == NULL)
                    {
                        temp->right = p;
                        p->right =NULL;
                        break;
                    }
                    else if(temp->col < p->col && temp->right->col>p->col)
                    {
                        p->right = temp->right;
                        temp->right = p;
                        break;
                    }
                    else if(temp==M->rh[p->row] && temp->col>p->col)
                    {
                        p->right = temp;
                        temp=p;
                        break;
                    }
                }

            }

   /*         if(M->ch[p->col] == NULL|| M->ch[p->col]->row>(p->row))
            {

                p->down=M->ch[p->col];
                M->ch[p->col] = p;
            }
            else
            {
                for(temp=M->ch[p->col]; temp->down && temp->down->row<p->row; temp=temp->down);

                p->down = temp->down;
                temp->down = p;
            }*/
        }
    }

}

void PlusToA(LCROSS A,LCROSS B)
{
    int i;
    LNODE p,temp1,temp2;
    for(i=1; i<=A->ra; i++)
    {
        if(B->rh[i] == NULL) continue;
        else
        {
            if(A->rh[i] == NULL)
            {

                p=(LNODE)malloc(sizeof(NODE));
                p->col = B->rh[i]->col;
                p->row = B->rh[i]->row;
                p->data = B->rh[i]->data;
                A->rh[i]=p;
                p->right = NULL;
                B->rh[i]=B->rh[i]->right;

            }
            if(B->rh[i]==NULL)continue;
            for(temp1=B->rh[i];; temp1=temp1->right)
            {
                for(temp2=A->rh[i];; temp2=temp2->right)
                {
                    if(temp2->col == temp1->col)
                    {
                        temp2->data+=temp1->data;
                        break;
                    }
                    else if(temp2==A->rh[i] && temp1->col<temp2->col)
                    {
                        p=(LNODE)malloc(sizeof(NODE));
                        p->col = temp1->col;
                        p->row = temp1->row;
                        p->data = temp1->data;
                        p->right = temp2->right;
                        p->right =temp2;
                        A->rh[i]=p;
                        break;
                    }
                    else if((temp2->right == NULL || temp2->right->col>temp1->col)  && temp1->col>temp2->col)
                    {
                        p=(LNODE)malloc(sizeof(NODE));
                        p->col = temp1->col;
                        p->row = temp1->row;
                        p->data = temp1->data;
                        p->right = temp2->right;
                        temp2->right=p;
                        break;
                    }

                }

                if(temp1->right == NULL) break;
            }
        }
    }

}

void PrintCross(LCROSS A)
{
    int i;
    LNODE p;
    for(i=1; i<=A->ra; i++)
    {
        p=A->rh[i];
        while(p!=NULL)
        {
            printf("%d %d %d\n",p->row,p->col,p->data);
            p=p->right;
        }
    }
}

TIP:

1、仅使用了十字链表中的行链表,列链表被凝视掉了,由于本题中没用。

2、注意改动链表时一定要改动原链表变量!!

如,定义链表A。temp=A。改动temp=p不能达到改动链表A=p的目的。

时间: 2024-09-29 18:33:29

稀疏矩阵的加法(用十字链表实现A=A+B)的相关文章

稀疏矩阵的压缩存储--十字链表(转载)

body { font-family: 微软雅黑,"Microsoft YaHei", Georgia,Helvetica,Arial,sans-serif,宋体, PMingLiU,serif; font-size: 10.5pt; line-height: 1.5; } html, body { } h1 { font-size:1.5em; font-weight:bold; } h2 { font-size:1.4em; font-weight:bold; } h3 { fon

十字链表

今天研究了一下十字链表,当稀疏矩阵的内部元素经常变化时,用三元顺序表操作起来比较麻烦,故用链表来实现对稀疏矩阵的存储,由于矩阵具有二维特性,单链表显然不适用,采用十字链表来实现对稀疏矩阵的存储. 十字链表有三种结点,1.总表头结点 2.行列表头结点 3.非零元素结点.下面一一介绍 1.总表头结点 共有5个子域 Row Col Next Down Right Row总行数 Col 总列数 Next 指向第一个行列表头结点 down和right两个指针域空置 2.行列表头结点 行列表头结点的结构与总

稀疏矩阵的十字链表存储表示

/* Name: 稀疏矩阵的十字链表存储表示 Copyright: Author: 巧若拙 Date: 29-10-14 21:25 Description: //------------------------------------------------------------------------- 除了用三元组顺序表来存储压缩矩阵,我们还可以用链表结构来存储,实际上后者应用更广泛, 因为当非零元素的数目较大时,三元组的时间复杂度实在太高.链表结构中最常见的是十字链表, 在十字链表中,

基于十字链表的两个稀疏矩阵相乘

#include <stdio.h> #include <stdlib.h> #include <string.h> typedef int DataType;// 稀疏矩阵的十字链表存储表示 typedef struct LNode { int i,j; // 该非零元的行和列下标 DataType e; // 非零元素值 struct LNode *right,*down; // 该非零元所在行表和列表的后继链域 }LNode, *Link; typedef str

看数据结构写代码(21) 稀疏矩阵(十字链表方式)

写完 这个样例,花费了 我不少时间.大部分时间 花费在 调试 内存问题上. 比如在销毁十字链表时.多次释放节点空间,造成 _CrtIsValidHeapPointer(pUserData) 异常. 当使用malloc 分配 一个 空间时,会将这个空间的起始地址和长度 加到一个链表中去.free(p)的时候 ,会从 链表里 查找 是否 有 这个地址空间,找到了就将这个节点从链表中删除._CrtIsValidHeapPointer(pUserData)  这个函数 正是 检查 这个空间是否 在链表里

_DataStructure_C_Impl:稀疏矩阵十字链表存储

#include<stdio.h> #include<stdlib.h> typedef int DataType; typedef struct OLNode{ int i,j; DataType e; struct OLNode *right,*down; }OLNode,*OLink; typedef struct{ OLink *rowhead,*colhead; int m,n,len; }CrossList; //初始化稀疏矩阵 void InitMatrix(Cros

javascript实现数据结构:稀疏矩阵的十字链表存储表示

当矩阵的非零个数和位置在操作过程中变化大时,就不宜采用顺序存储结构来表示三元组的线性表.例如,在作"将矩阵B加到矩阵A上"的操作时,由于非零元的插入或删除将会引起A.data中元素的移动.为此,对这种类型的矩阵,采用链式存储结构表示三元组的线性表更为恰当. 在链表中,每个非陵园可用一个含5个域的结点表示,其中i,j和e这3个域分别表示该非零元所在的行,列和非零元的值,向右域right用以链接同一行中下一个非零元,向下域down用以链接同一列中下一个非零元.同一行的非零元通过right域

数据结构之---C/C++实现稀疏矩阵的十字链表

首先这里介绍什么是矩阵的十字链表,大家可以理解稀疏矩阵是顺序存储的,那么这个就是链式存储的. 如图: 存储该矩阵 那么应该是如下的格式: 我们知道稀疏矩阵的三元组存储方式的实现很简单,每个元素有三个域分别是col,row, e.代表了该非零元的行号.列号以及值.那么在十字链表的存储方式下,首先这三个域是肯定少不了的,不然在进行很多操作的时候都要自己使用计数器,很麻烦.而十字链表的形式大家可以理解成每一行是一个链表,而每一列又是一个链表 通过上面的图我们可以知道,每个结点不止要存放row, col

经典算法题每日演练——第二十一题 十字链表

原文:经典算法题每日演练--第二十一题 十字链表 上一篇我们看了矩阵的顺序存储,这篇我们再看看一种链式存储方法“十字链表”,当然目的都是一样,压缩空间. 一:概念 既然要用链表节点来模拟矩阵中的非零元素,肯定需要如下5个元素(row,col,val,down,right),其中: row:矩阵中的行. col:矩阵中的列. val:矩阵中的值. right:指向右侧的一个非零元素. down:指向下侧的一个非零元素. 现在我们知道单个节点该如何表示了,那么矩阵中同行的非零元素的表示不就是一个单链