繁体   English   中英

除了稀疏矩阵 C 程序之外,值未存储在链表中

[英]Values not getting Stored in Linked List in Addition of Sparse matrix C Program

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

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

//Suyash Ekhande's 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;
}

预期的 output 应该是链表形式的第三个矩阵。 但是 Output 提示矩阵 1 和 2 为 Null 由条件检查。

在您的addMat2value function 中,应该将条目添加到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:: 虽然您可以定义单个 function 并将m1m2列表作为参数传递给它。

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

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

  • 最明显的错误是您的函数对三个全局变量m1m2和“m3”进行操作。 然后,您编写专用于这些值的函数。 您的函数应该将矩阵作为 arguments。 没有必要编写三个基本上做同样事情的打印函数,只是针对不同的矩阵。 (这种复制和过去的编程也为拼写错误提供了充足的机会,如您的代码所示。)

  • 当您添加矩阵时,您依赖于特定的排序,但是(1)您在构造矩阵时不强制执行该排序,并且(2)您强制排序的方式不起作用,因为它不是唯一的:条件r1 < r2 || c1 < c2 r1 < r2 || c1 < c2r1 > r2 || c1 > c2 r1 > r2 || c1 > c2不是互斥的。

  • 当您在末尾插入节点时,您必须使用while (m->next)...遍历列表,因为您想要获取最后一个节点。 当您打印列表时,您应该使用while (m)... ,否则您将跳过最后一个节点。

  • 通常,您的控制流有太多重复的代码。 无需将读取代码放入if , foe 示例的每个分支中。 这应该是通用代码。 理想情况下,读取和插入节点的代码应该是分开的。

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

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;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM