使用C语言中的链表创建稀疏矩阵
我有一个任务是创建两个稀疏矩阵(A和B),然后将它们相加到第三个稀疏矩阵(C)。我已经用向量做过了(接收两个稀疏向量并将它们添加到第三个向量中),所以我决定使用一系列向量来表示矩阵会更容易。将来,我可能需要不使用向量而使用实际矩阵(我甚至有一个函数的psuedo代码,它将一个数字插入稀疏矩阵),所以一定要理解为什么我要问所有这些,即使下面的代码有点起作用 因为它是一个矩阵,所以它有两个指针数组,即行数组和列数组。数组的每个单元格都指向相应的行/列。如下图所示: 作为一个稀疏矩阵,其中有零,您可以看到这些箭头,因为带有零的节点不存在 为了简化问题,我宁愿只处理行数组,如图所示,这些行指向每一新行的头。假设每一行是一个向量C(就像我上面说的,我想用一系列向量来表示矩阵) 这是我构建的所有链表函数的代码:使用C语言中的链表创建稀疏矩阵,c,sparse-matrix,C,Sparse Matrix,我有一个任务是创建两个稀疏矩阵(A和B),然后将它们相加到第三个稀疏矩阵(C)。我已经用向量做过了(接收两个稀疏向量并将它们添加到第三个向量中),所以我决定使用一系列向量来表示矩阵会更容易。将来,我可能需要不使用向量而使用实际矩阵(我甚至有一个函数的psuedo代码,它将一个数字插入稀疏矩阵),所以一定要理解为什么我要问所有这些,即使下面的代码有点起作用 因为它是一个矩阵,所以它有两个指针数组,即行数组和列数组。数组的每个单元格都指向相应的行/列。如下图所示: 作为一个稀疏矩阵,其中有零,您可
typedef struct List_node
{
int key;
int i,j;
struct List_node *next;
}List_node;
typedef struct List
{
List_node *head;
}List;
List *create_list()
{
List *list = (List*)malloc(sizeof(List));
list->head = NULL;
return list;
}
void insert_first(List_node *x, List *list)
{
x->next = list->head;
list->head = x;
}
void insert(List_node *x, List_node *y)
{
x->next = y->next;
y->next = x;
}
List_node *mk_node(int data, int row, int col)
{
List_node *node = (List_node *)malloc(sizeof(List_node));
node->key = data;
node->i = row + 1;
node->j = col + 1;
return node;
}
void delete_list(List *list)
{
List_node *node, *temp;
node = list->head;
while (node != NULL)
{
temp = node->next;
free(node);
node = temp;
}
free(list);
}
void print_list(List *list, char name)
{
List_node *p;
p = list->head;
printf("\nThe linked list %c consists of: ",name);
while (p != NULL)
{
printf("%d(i = %d) (j = %d) ", p->key, p->i, p->j);
p = p->next;
}
printf("\n");
}
这是创建向量的代码:
List *Create_vector (List *A, List *B, int i, int m)
{
int l,flag = 0;
List *C;
List_node *node=NULL, *next, *Pointer_A, *Pointer_B;
C = create_list();
Pointer_A = A->head;
Pointer_B = B->head;
for (l = 0; l<m; l++)
{
if ((Pointer_A->key + Pointer_B->key) != 0)
{
if (flag == 0)
{
node = mk_node(Pointer_A->key + Pointer_B->key, i,l);
insert_first(node, C);
flag = 1;
}
else
{
next = mk_node(Pointer_A->key + Pointer_B->key, i,l);
insert(next, node);
node = next;
}
}
Pointer_A = Pointer_A->next;
Pointer_B = Pointer_B->next;
}
return C;
}
List*创建向量(List*A,List*B,int i,int m)
{
int l,flag=0;
清单*C;
List_node*node=NULL,*next,*Pointer_A,*Pointer_B;
C=创建_列表();
指针A=A->head;
指针B=B->head;
对于(l=0;lkey+指针\U B->键)!=0)
{
如果(标志==0)
{
node=mk_节点(指针A->key+指针B->key,i,l);
首先插入_(节点C);
flag=1;
}
其他的
{
next=mk_节点(指针A->键+指针B->键,i,l);
插入(下一步,节点);
节点=下一个;
}
}
指针A=指针A->next;
指针\u B=指针\u B->下一步;
}
返回C;
}
这是主要的节目:
void main()
{
List_node *Row_A, *Row_B, *Row_C;
List *A, *B, *C;
List_node *node, *next;
int data, m,n,l;
printf("Enter list row\n");
scanf("%d", &m);
Row_A = (List_node*)malloc(sizeof(int)*(m));
Row_B = (List_node*)malloc(sizeof(int)*(m));
Row_C = (List_node*)malloc(sizeof(int)*(m));
printf("Enter list columns\n");
scanf("%d", &n);
for (int i=0; i<m; i++)
{
A = create_list();
B = create_list();
printf("\nInsert first number into A\n");
scanf("%d", &data);
node = mk_node(data, i,0);
insert_first(node, A);
for (l = 1; l<n; l++)
{
printf("Now insert the rest of the numbers\n");
scanf("%d", &data);
next = mk_node(data, i,l);
insert(next, node);
node = next;
}
print_list(A,'A');
printf("\nInsert first number into B\n");
scanf("%d", &data);
node = mk_node(data,i,0);
insert_first(node, B);
for (l = 1; l<n; l++)
{
printf("Now insert the rest of the numbers\n");
scanf("%d", &data);
next = mk_node(data, i,l);
insert(next, node);
node = next;
}
print_list(B,'B');
C = Create_vector(A,B,i,n);
}
getchar(); getchar();
}
void main()
{
列表节点*行A、*行B、*行C;
名单*A、*B、*C;
列出_节点*节点,*下一步;
int数据,m,n,l;
printf(“输入列表行\n”);
scanf(“%d”、&m);
行A=(列表节点*)malloc(sizeof(int)*(m));
行B=(列表节点*)malloc(sizeof(int)*(m));
行C=(列表节点*)malloc(sizeof(int)*(m));
printf(“输入列表列\n”);
scanf(“%d”和“&n”);
对于(int i=0;i一些可能让您开始的观察:
- 您可以按照创建动态数组的方式创建头列表。这些头列表不应该是独立的数据结构。它们应该是
矩阵
结构的一部分,就像头
是列表
结构的一部分一样。头数组的分配应该是其crea的一部分tor函数创建矩阵
- 每个
矩阵
存储自己的头列表这一事实也是覆盖C
的解决方案:要反复分配给C
,请分配给C->head[i]
。同样,对于A
和B
。描述矩阵的所有日期都应封装在一个结构中,以便将所有内容整齐地存储在一起
- 此时,将矩阵表示为行列表。这对于打印和矩阵加法很好,但一旦进行乘法运算,还需要列标题。然后,节点结构必须准备好两个指针,如草图所示:一个指针用于行中的下一个元素(
右侧
,例如)一个用于列中的下一个元素()
- 矩阵不是稀疏的。例如,添加两个列表的代码(不应称为
create_vector
;选择更具表现力的内容)应检查与节点关联的索引,以便跳过零个条目
- 您应该将列表或矩阵的维度存储在结构中。遍历列表时不需要这样做,但可以快速检查操作是否合法。例如,您只能添加相同维度的矩阵
例如:
typedef struct Matrix Matrix;
typedef struct Matrixnode Matrixnode;
struct Matrix {
int n, m;
Matrixnode *row;
Matrixnode *col;
};
Matrix *create_matrix(int n, int m)
{
Matrix *mx = malloc(sizeof(*mx));
mx->n = n;
mx->m = m;
mx->row = malloc(m * sizeof(*m->row));
mx->col = malloc(n * sizeof(*n->col));
return mx;
}
Matrix *matrix_add(const Matrix *a, const Matrix *b)
{
assert(a->m == b->m);
assert(a->n == b->n);
Matrix *c = create_matrix(a->n, a->m);
for (int i = 0; i < c->m; i++) {
c->row[i] = row_add(a->row[i], b->row[i]);
}
return c;
}
typedef结构矩阵;
类型定义结构矩阵节点矩阵节点;
结构矩阵{
int n,m;
矩阵节点*行;
矩阵节点*col;
};
矩阵*创建矩阵(整数n,整数m)
{
矩阵*mx=malloc(sizeof(*mx));
mx->n=n;
mx->m=m;
mx->row=malloc(m*sizeof(*m->row));
mx->col=malloc(n*sizeof(*n->col));
返回mx;
}
矩阵*矩阵加(常数矩阵*a,常数矩阵*b)
{
断言(a->m==b->m);
断言(a->n==b->n);
矩阵*c=创建矩阵(a->n,a->m);
对于(int i=0;im;i++){
c->行[i]=行添加(a->行[i],b->行[i]);
}
返回c;
}
这是如何创建行向量数组的粗略示意图。(我创建了一个col
数组,但不使用它。添加矩阵时,还必须注意保持列指针的一致性。)谢谢。你能详细说明第一个和第二个观察结果吗,甚至可以在示例代码中说明你的意思吗?这会很有帮助,因为我不确定我是否理解你的意思。另外,关于你的第四个观察结果,请注意,如果((指针a->键+指针B->键)!=0)
在create_vector
函数中,确保跳过零个条目。