我正在尝试使用链表添加 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,这是通过条件检查的。
在您的
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
您的代码有很多错误,包括概念缺陷和实际语法错误。
你所谓的稀疏矩阵并不是真正的矩阵,它只是一个没有重复项的(行,列,值)项的链接列表。实数矩阵需要有关其行数和列数的信息。如何有效地找到细胞?你将如何进行矩阵乘法?作为 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;
}