添加稀疏矩阵 C 程序时,值未存储在链接列表中

问题描述 投票:0回答:2

我正在尝试使用链表添加 2 个稀疏矩阵。 我接受 2 个矩阵的值 将它们相加并将它们存储到第三个矩阵中。 但由于某种原因,这些值没有存储在链表中,存在一些内存问题。

我尝试检查在链表末尾添加节点的条件。

//Approach to Sparse matrix Addition and Substraction.
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
struct SparseMatrix
{
    int row;
    int col;
    int val;
    struct SparseMatrix *next;
};
struct SparseMatrix *m1;
struct SparseMatrix *m2;
struct SparseMatrix *m3;

void printM1M2()
{
    struct SparseMatrix *mm1,*mm2;
    mm1=m1;
    mm2=m2;
    
    printf("Matrix1: \n");
    while(mm1->next!=NULL)
    {
        printf("Row: %d\tCol: %d\tVal: %d\n",mm1->row,mm1->col,mm1->val);
        mm1=mm1->next;
    }
    printf("Matrix2: \n");
    while(mm1->next!=NULL)
    {
        printf("Row: %d\tCol: %d\tVal: %d\n",mm2->row,mm2->col,mm2->val);
        mm2=mm2->next;
    }
}

void addMat1Values()
{
    struct SparseMatrix *ptr,*tmp;
    int row,col,val;
    ptr = (struct SparseMatrix*)malloc(sizeof(struct SparseMatrix));
    
    if(m1 == NULL)
    {
        printf("\nEnter Row Column and Value\n");
        scanf("%d %d %d",&row, &col, &val);
        ptr->row=row;
        ptr->col=col;
        ptr->val=val;
        ptr->next = NULL;
        m1 = ptr;
        
        printf("\n1st Node inserted");
    }
    else
    {
        tmp=m1;
        printf("\nEnter Row Column and Value\n");
            scanf("%d %d %d",&row, &col, &val);
        while(tmp->next!=NULL)
        {
            tmp=tmp->next;
            
        }
            ptr->row=row;
            ptr->col=col;
            ptr->val=val;
            tmp->next=ptr;
            ptr->next=NULL;
    
    printf("\nNode inserted");
    }
}

void addMat2Values()
{
    struct SparseMatrix *ptr,*tmp;
    int row,col,val;
    ptr = (struct SparseMatrix*)malloc(sizeof(struct SparseMatrix));
    if(m2 == NULL)
    {
        printf("\nEnter Row Column and Value\n");
        scanf("%d %d %d",&row, &col, &val);
        ptr->row=row;
        ptr->col=col;
        ptr->val=val;
        ptr->next = NULL;
        m1 = ptr;
    
    }
    else
    {
        tmp=m1;
        while(tmp->next!=NULL)
        {
            tmp=tmp->next;
            
        }
        
        printf("\nEnter Row Column and Value\n");
            scanf("%d %d %d",&row, &col, &val);
            ptr->row=row;
            ptr->col=col;
            ptr->val=val;
            tmp->next=ptr;
            ptr->next=NULL;
    printf("\nNode inserted");
    }
}
void copyElement(int r,int c,int v)
{
    struct SparseMatrix *ptr,*temp;
    ptr = (struct SparseMatrix*)malloc(sizeof(struct SparseMatrix));
   
    ptr->row=r;
    ptr->col=c;
    ptr->val=v;
    if(m3 == NULL)
    {
        ptr -> next = NULL;
        m3 = ptr;
        printf("\nNode inserted");
    }
    else
    {
        temp = m3;
        while (temp -> next != NULL)
        {
            temp = temp -> next;
        }
        temp->next = ptr;
        ptr->next = NULL;
        printf("\nNode inserted");

    }
    }



void addTheMatrixFinally()
{
    struct SparseMatrix *mat1;
    struct SparseMatrix *mat2;
    mat1=m1;
    mat2=m2;

    if(mat1 == NULL || mat2 == NULL)
    {
        printf("Matrices are Null!!");
    }
    while(mat1 !=NULL && mat2!=NULL)
    {
        if(mat1->row == mat2->row && mat1->col == mat2->col)
        {
            int row,col,val;
            row=mat1->row;
            col=mat1->col;
            val=mat1->val + mat2->val;
            copyElement(row,col,val);
              mat1=mat1->next;
            mat2=mat2->next;
        }
        else if(mat1->row < mat2->row || mat1->col < mat2->col)
        {//mat 1 ele is smaller
         //copy the element to final matrix
         copyElement(mat1->row,mat1->col,mat1->val);
         mat1=mat1->next;
         //go to next element
        }
        else if(mat1->row > mat2->row || mat1->col > mat2->col)
        {//mat 2 ele is smaller
            //copy the element to final matrix
         copyElement(mat1->row,mat1->col,mat1->val);
         mat2=mat2->next;
         //go to next element
        }

    }
}

void printSparseMatrix()
{
    int r,c,v;
    struct SparseMatrix *mat;
    mat = m3;

    if(mat == NULL)
    {
    printf("\n result matrice are null");
    }
    else
    {
        while(mat->next!=NULL)
        {
            r=mat->row;
            c=mat->col;
            v=mat->val;
            printf("Row: %d\tCol: %d\tVal: %d",r,c,v);
            mat=mat->next;
        }
    }
}

int main()
{
    int l,i, j;
    clrscr();
    printf("Enter Number of Elements: ");
    scanf("%d",&l);
    printf("Enter Matrix 1 Elements");
    for(i=0;i<l;i++)
    {
        addMat1Values();
    }
    printf("\nEnter Matrix 2 Elements");
    for(j=0;j<l;j++)
    {
        addMat2Values();    
    }
    printM1M2();
    addTheMatrixFinally();
    printSparseMatrix();

    getch();
    return 0;
}

预期输出应该是以链表形式显示的第三个矩阵。 但输出提示矩阵 1 和 2 为 Null,这是通过条件检查的。

c data-structures linked-list
2个回答
1
投票

在您的

addMat2value
函数中,本应将条目添加到
m2
列表,但实际上是将条目添加到
m1
列表。

void addMat2Values()
{
    struct SparseMatrix *ptr,*tmp;
    int row,col,val;
    ptr = (struct SparseMatrix*)malloc(sizeof(struct SparseMatrix));
    if(m2 == NULL)
    {
        printf("\nEnter Row Column and Value\n");
        scanf("%d %d %d",&row, &col, &val);
        ptr->row=row;
        ptr->col=col;
        ptr->val=val;
        ptr->next = NULL;
        m1 = ptr;

    }
    else
    {
        tmp=m1;
        while(tmp->next!=NULL)
        {
            tmp=tmp->next;

        }

        printf("\nEnter Row Column and Value\n");
            scanf("%d %d %d",&row, &col, &val);
            ptr->row=row;
            ptr->col=col;
            ptr->val=val;
            tmp->next=ptr;
            ptr->next=NULL;
    printf("\nNode inserted");
    }
}

应该是

void addMat2Values()
{
    struct SparseMatrix *ptr,*tmp;
    int row,col,val;
    ptr = (struct SparseMatrix*)malloc(sizeof(struct SparseMatrix));
    if(m2 == NULL)
    {
        printf("\nEnter Row Column and Value\n");
        scanf("%d %d %d",&row, &col, &val);
        ptr->row=row;
        ptr->col=col;
        ptr->val=val;
        ptr->next = NULL;
        m2 = ptr;

    }
    else
    {
        tmp=m2;
        while(tmp->next!=NULL)
        {
            tmp=tmp->next;

        }

        printf("\nEnter Row Column and Value\n");
            scanf("%d %d %d",&row, &col, &val);
            ptr->row=row;
            ptr->col=col;
            ptr->val=val;
            tmp->next=ptr;
            ptr->next=NULL;
    printf("\nNode inserted");
    }
}

Aside :: 虽然你可以只定义单个函数并且 传递

m1
m2
列表作为其参数。


0
投票

您的代码有很多错误,包括概念缺陷和实际语法错误。

  • 你所谓的稀疏矩阵并不是真正的矩阵,它只是一个没有重复项的(行,列,值)项的链接列表。实数矩阵需要有关其行数和列数的信息。如何有效地找到细胞?你将如何进行矩阵乘法?作为 s,coe 仅对加法和减法有用。

  • 最明显的错误是你的函数对三个全局变量

    m1
    m2
    和´m3`进行操作。然后,您可以编写专门针对这些值的函数。您的函数应该将矩阵作为参数。无需编写三个基本上执行相同操作的打印函数,仅针对不同的矩阵。 (正如您的代码所示,这种复制粘贴的编程也为拼写错误提供了充足的机会。)

  • 当您添加矩阵时,您依赖于某种排序,但是(1)您在构造矩阵时不会强制执行该排序,并且(2)强制执行排序的方式不起作用,因为它不是唯一的:条件

    r1 < r2 || c1 < c2
    r1 > r2 || c1 > c2
    并不相互排斥。

  • 当你在末尾插入节点时,你必须用

    while (m->next) ...
    迭代列表,因为你想得到最后一个节点。当你打印列表时,你应该使用
    while (m) ...
    ,否则你会跳过最后一个节点。

  • 一般来说,你的控制流有太多重复的代码。无需将读取代码放入

    if
    示例的每个分支中。这应该是通用代码。理想情况下,读取和插入节点的代码应该是分开的。

以下简单修复将使您的代码打印结果矩阵。不过,该矩阵可能不正确,因为此处未解决排序问题:

In printM1M2, line 6:           while(mm1!=NULL)        // was: mm1->next
In printM1M2, line 12:          while(mm2!=NULL)        // was: mm2->next

In addMat2Values, line 12:      m2 = ptr;               // was: m1 = ptr
In addMat2Values, line 17:      tmp=m2;                 // was: tmp=m1

下面是一个有效的实现。它使用

main
中的三个局部变量作为矩阵,按特定顺序插入节点,并在添加矩阵时使用该顺序。它还会在使用后释放链接列表。 (这里就不多解释了,详细请看其他答案。)

#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>

typedef struct Sparse Sparse;

struct Sparse {
    int row;
    int col;
    int val;
    Sparse *next;
};

/*
 *      Nodes that are "less" than others come first in the list.
 */
bool sp_less(const Sparse *a, const Sparse *b)
{
    if (a->row < b->row) return true;
    if (a->row > b->row) return false;
    return (a->col < b->col);
}

/*
 *      Add a value to the matrix at row, col.
 */
void sp_set(Sparse **sp, int row, int col, int val)
{
    Sparse *sn = malloc(sizeof(*sn));

    sn->row = row;
    sn->col = col;
    sn->val = val;
    sn->next = NULL;

    while (*sp && sp_less(*sp, sn )) {
        sp = &(*sp)->next;
    }

    if (*sp == NULL || sp_less(sn, *sp)) {
        sn->next = *sp;
        *sp = sn;
    } else {
        (*sp)->val += val;
        free(sn);
    }
}

/*
 *      Print the non-null elements of a matrix
 */
void sp_print(const Sparse *sp, const char *name)
{
    while (sp) {
        printf("%s(%d, %d) == %d\n",
            name, sp->col, sp->row, sp->val);
        sp = sp->next;
    }

    puts("");
}

/*
 *      Destroy a matrix and free the memory.
 */
void sp_destroy(Sparse *sp)
{
    while (sp) {
        Sparse *next = sp->next;

        free(sp);
        sp = next;
    }
}

/*
 *      Add two matrices and return the new matrix
 */
Sparse *sp_add(const Sparse *a, const Sparse *b)
{
    Sparse *res = NULL;

    while (a && b) {
        if (sp_less(a, b)) {
            sp_set(&res, a->row, a->col, a->val);
            a = a->next;
        } else if (sp_less(b, a)) {
            sp_set(&res, b->row, b->col, b->val);
            b = b->next;
        } else {
            sp_set(&res, b->row, b->col, a->val + b->val);
            a = a->next;
            b = b->next;
        }
    }

    while (a) {
        sp_set(&res, a->row, a->col, a->val);
        a = a->next;
    }

    while (b) {
        sp_set(&res, b->row, b->col, b->val);
        b = b->next;
    }

    return res;
}

/*
 *      Hard-coded example.
 */
int main(void)
{
    Sparse *a = NULL;
    Sparse *b = NULL;
    Sparse *res = NULL;

    sp_set(&a, 0, 0, 1);
    sp_set(&a, 1, 1, 1);
    sp_set(&a, 2, 2, 1);
    sp_print(a, "a");

    sp_set(&b, 2, 0, 1);
    sp_set(&b, 1, 1, 1);
    sp_set(&b, 0, 2, 1);
    sp_print(b, "b");

    res = sp_add(a, b);
    sp_print(res, "res");

    sp_destroy(a);
    sp_destroy(b);
    sp_destroy(res);

    return 0;
}
© www.soinside.com 2019 - 2024. All rights reserved.