我正在尝试使用链表添加 2 个稀疏矩阵。 我接受 2 个矩阵的值 将它们添加并存储到第三个矩阵中。 但是由于某种原因,值没有存储在链表中,存在一些内存问题。
我尝试检查在链表中末尾添加节点的条件。
//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: %dtCol: %dtVal: %dn",mm1->row,mm1->col,mm1->val);
mm1=mm1->next;
}
printf("Matrix2: n");
while(mm1->next!=NULL)
{
printf("Row: %dtCol: %dtVal: %dn",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 Valuen");
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 Valuen");
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 Valuen");
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 Valuen");
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: %dtCol: %dtVal: %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 Valuen");
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 Valuen");
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 Valuen");
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 Valuen");
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");
}
}
除了 :: 虽然你可以只定义单个函数和 传递
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) == %dn",
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;
}