具有链表的稀疏矩阵

时间:2016-10-28 22:06:26

标签: c list matrix linked-list sparse-matrix

我尝试使用链接列表在C中创建稀疏矩阵。我的教授给出了file.h结构,一系列功能以及它们应该做什么,并告诉我们使用它"使用它"。 要恢复所有内容,我的代码不起作用,当我尝试插入元素(调用ins_elem())并在调用soma_elem_coluna()soma_elem_linha()时返回奇怪的数字时,它会停止工作。

我已将整个代码放在下面,但问题实际上在上面指定的函数内(而soma_const()因为我无法在不插入元素的情况下对其进行测试)。

我使用的逻辑是创建一个矩阵,如下图所示(用数字代替字符) [1]

不要介意奇怪的打字,有些单词是葡萄牙语。

(C =列,L =行)

这是我的file.h

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LINES 4
#define COLUM 4

typedef struct Node{
    int Val, L, C;
    struct Node *down, *right;
}Node;

typedef struct{
    Node *L[LINES], *C[COLUM];
}matriz;

void cria_matriz(matriz* m);                       // creates matrix
void ins_elem(matriz* m, int e, int l, int c);     // insert element e into lxc 
void soma_const(matriz* m, int e, int l, int c);   // add value e to existing lxc
int soma_elem_linha(matriz *m, int l);             // sums all the values in row l
int soma_elem_coluna(matriz *m, int c);            // sums all the values in column c
void imp(matriz *m);                               // prints the matrix

我的file.c

#include "file.h"

void cria_matriz(matriz* m) 
{
    int i;
    for(i=0;i<LINES;i++) //initializes headrows
    {
        m->L[i]->down = NULL;
        m->L[i]->right = NULL;
        m->L[i]->C = -1;
        m->L[i]->L = -1;
    }
    for(i=0;i<COLUM;i++) //initializes headcolumns
    {
        m->C[i]->down = NULL;
        m->C[i]->right = NULL;
        m->C[i]->C = -1;
        m->C[i]->L = -1;
    }
}

void ins_elem(matriz *m, int e, int l, int c)
{
    Node* auxLine; // move through row
    Node* auxCol; // move through column
    auxLine = &m->L[l];
    auxCol = &m->C[c];
    while(auxLine->right != NULL && auxLine->right->C < c) //find correct pos in row
    {
        auxLine = auxLine->right;
    }
    while(auxCol->down != NULL && auxCol->down->L < c) //find correct pos in column (error happens here)
    {
        auxCol = auxCol->down;
    }
    Node* novo = malloc(sizeof(Node));
    novo->Val = e;
    novo->C = c;
    novo->L = l;
    novo->down = auxCol->down;
    auxCol->down = novo;
    novo->right = auxLine->right;
    auxLine->right = novo;
}

void soma_const(matriz *m, int e, int l, int c)
{
    Node* aux = &m->C[c];
    while(aux->down != NULL && aux->L < l)
        aux = aux->down;
    aux->Val+=e;
}

int soma_elem_coluna(matriz *m, int c)
{
    int sum = 0;
    Node* aux = &m->C[c];
    if(aux->down == NULL)
        return 0;
    while(aux->down != NULL)
    {
        aux = aux->down;
        sum += aux->Val;
    }
    return sum;
}

int soma_elem_linha(matriz *m, int l)
{
    int sum = 0;
    Node* aux = &m->L[l];
    if(aux->right == NULL)
        return 0;
    while(aux->right != NULL)
    {
        aux = aux->right;
        sum += aux->Val;
    }
    return sum;
}

void imp(matriz *m)
{
    Node* aux;
    int i, j;
    for(i=0;i<LINES;i++)
    {
        aux = &m->L[i];
        for(j=0;j<COLUM;j++)
        {
            if(aux->C == j)
            {
                printf("%d ",aux->Val);
                aux = aux->right;
            }
            else
            {
                printf("0 ");
            }
        }
        printf("\n");
    }
}

我的main.c

#include "file.h"

int main()
{
    struct matriz* M = (matriz*)malloc(sizeof(matriz));
    int i,e,c,l,result;
    char str[20];
    for(i=0;i<5;i++) // this is temporary and another issue, how I make a while that 
    {                 // only stops when user (a bot actually) presses enter?
        scanf(" %s",str);

        if(!strcmp(str,"cria_matriz"))
        {
            cria_matriz(M);
        }
        else if(!strcmp(str,"ins_elem"))
        {
            scanf("%d %d %d",&e,&l,&c);
            ins_elem(M,e,l,c);
        }
        else if(!strcmp(str,"soma_const"))
        {
            scanf("%d %d %d",&e,&l,&c);
            soma_const(M,e,l,c);
        }
        else if(!strcmp(str,"soma_elem_linha"))
        {
            scanf("%d",&l);
            result = soma_elem_linha(M,l);
            printf("%d\n",result);
        }
        else if(!strcmp(str,"soma_elem_coluna"))
        {
            scanf("%d",&c);
            result = soma_elem_coluna(M,c);
            printf("%d\n",result);
        }
        else if(!strcmp(str,"imp"))
        {
            imp(M);
        }
    }
    return 0;
}

1 个答案:

答案 0 :(得分:0)

由于代码中存在大量指针和其他问题,因此您的文件在没有警告的情况下无法编译。我已经研究过你的代码来清理警告,但是我无法测试逻辑 - 你必须这样做:

<强> file.c

#include "file.h"

void cria_matriz(matriz *m) 
{
    for (int i = 0; i < LINES; i++) // initializes headrows
    {
        m->L[i] = malloc(sizeof(Node));
        m->L[i]->down = NULL;
        m->L[i]->right = NULL;
        m->L[i]->C = -1;
        m->L[i]->L = -1;
        m->L[i]->Val = 0;
    }

    for (int i = 0; i < COLUM; i++) // initializes headcolumns
    {
        m->C[i] = malloc(sizeof(Node));
        m->C[i]->down = NULL;
        m->C[i]->right = NULL;
        m->C[i]->C = -1;
        m->C[i]->L = -1;
        m->C[i]->Val = 0;
    }
}

void ins_elem(matriz *m, int e, int l, int c)
{
    Node *auxLine = m->L[l]; // move through row
    Node *auxCol = m->C[c]; // move through column

    while (auxLine->right != NULL && auxLine->right->C < c) // find correct pos in row
    {
        auxLine = auxLine->right;
    }

    while (auxCol->down != NULL && auxCol->down->L < c) // find correct pos in column (error happens here)
    {
        auxCol = auxCol->down;
    }

    Node *novo = malloc(sizeof(*novo));
    novo->Val = e;
    novo->C = c;
    novo->L = l;
    novo->down = auxCol->down;

    auxCol->down = novo;
    novo->right = auxLine->right;
    auxLine->right = novo;
}

void soma_const(matriz *m, int e, int l, int c)
{
    Node *aux = m->C[c];

    while (aux->down != NULL && aux->L < l)
    {
        aux = aux->down;
    }

    aux->Val += e;
}

int soma_elem_coluna(matriz *m, int c)
{
    Node *aux = m->C[c];

    if (aux->down == NULL) {
        return 0;
    }

    int sum = 0;

    while (aux->down != NULL)
    {
        aux = aux->down;
        sum += aux->Val;
    }

    return sum;
}

int soma_elem_linha(matriz *m, int l)
{
    Node *aux = m->L[l];

    if (aux->right == NULL) {
        return 0;
    }

    int sum = 0;

    while (aux->right != NULL)
    {
        aux = aux->right;
        sum += aux->Val;
    }

    return sum;
}

void imp(matriz *m)
{
    for (int i = 0; i < LINES; i++)
    {
        Node *aux = m->L[i];

        for (int j = 0; j < COLUM; j++)
        {
            if (aux->C == j)
            {
                printf("%d ", aux->Val);
                aux = aux->right;
            }
            else
            {
                printf("0 ");
            }
        }

        printf("\n");
    }
}

<强>的main.c

#include "file.h"

int main()
{
    matriz *M = malloc(sizeof(*M));
    int e, c, l;
    char str[32];

    for (int i = 0; i < 5; i++) // this is temporary and another issue, how I make a while that 
    {               // only stops when user (a bot actually) presses enter?
        (void) scanf(" %s", str);

        if (strcmp(str, "cria_matriz") == 0)
        {
            cria_matriz(M);
        }
        else if (strcmp(str, "ins_elem") == 0)
        {   
            scanf("%d %d %d", &e, &l, &c);
            ins_elem(M, e, l, c);
        }
        else if (strcmp(str, "soma_const") == 0)
        {
            (void) scanf("%d %d %d", &e, &l, &c);
            soma_const(M, e, l, c);
        }
        else if (strcmp(str, "soma_elem_linha") == 0)
        {
            (void) scanf("%d", &l);
            int result = soma_elem_linha(M, l);
            printf("%d\n", result);
        }
        else if (strcmp(str, "soma_elem_coluna") == 0)
        {
            scanf("%d", &c);
            int result = soma_elem_coluna(M, c);
            printf("%d\n", result);
        }
        else if (strcmp(str,"imp") == 0)
        {
            imp(M);
        }
    }

    free(M);

    return 0;
}

最大的问题是你一直在指出那些已经指针的东西。此外,您初始化了您实际未分配的数据。您没有初始化随后添加到的某些数据。最后,strcmp()不是布尔值,不要将其用作一个布尔值。