user3699735
user3699735

Reputation: 21

Creating a Matrix using a linked list

I am having trouble with my display_matrix function in my program and I am also recieving a segmentation fault when I run my program, I don't know if that has to do with me not having a destroy_memory function yet or what. My program reads in the dimensions of the matrix, and then creates random numbers from 1 to 100 and makes the matrix, then displays it, then frees up the allocated memory. I believe for my display function that I have to use a nested for loop to print out the values. Any help is appreciated and thank you in advance. Here is the code that I have right now along with a sample output of my program.

#include<stdio.h>
#include<stdlib.h>
#include<time.h>

typedef struct MatrixNode_{
    int value;
    struct MatrixNode_ *next_row;
    struct MatrixNode_ *next_col;
}MatrixNode;

void create_linked_list_matrix(MatrixNode** head, const int rows, const int cols);
MatrixNode* create_node(void);
void display_matrix(MatrixNode* head);
void destroy_linked_list_matrix(MatrixNode** head);

int main (int argc, char *argv[]) {
    if (argc < 3) {
            exit(1);
    }
    srand(time(NULL));
    const int rows = atoi(argv[1]);
    const int cols = atoi(argv[2]);
    MatrixNode* head_a = NULL;
    printf("Matrix A\n");
    create_linked_list_matrix(&head_a,rows,cols);
    display_matrix(head_a);
    destroy_linked_list_matrix(&head_a);
}

MatrixNode* create_node(void){

    MatrixNode *temp = (MatrixNode *)malloc(sizeof(MatrixNode));
    if(temp == NULL){
    printf("Memory alloc error");
    exit(1);
    }
    temp->next_col = NULL;
    temp->next_row = NULL;
    temp->value = rand() % 100 + 1;
    return temp;
}

/*The MatrixNode double pointer will be NULL when first coming in, 
make sure to allocate     space  For it and adjust your linked list of linked    
list to start from 1 not 0. Next allocate a linked list of      
MatrixNodes using the next row as the next node in the linked list. 
You will need to create the linked list length up to the passed in rows value. 
After the allocation of the rows linked list,  we need to allocate a separate 
linked list  for each of the next_col MatrixNode pointers in the rows linked list.
 To create the linked list for the columns create the linked list of MatrixNodes
 using the next_col as the next node in the linked list. You will need to create 
the linked list    length up to the passed in cols value. 
Use the create_node function to     create  nodes for your linked list.
 */

void create_linked_list_matrix(MatrixNode **head, const int rows, const int cols){

   MatrixNode *tmpabove = NULL, *tmpleft = NULL, *tmpaboveleft = NULL, *newnode = NULL;

    int i, y;
    for( i = 0; i < rows; i++){
            tmpleft = NULL;
            for( y = 0; y < cols; y++){
            newnode = create_node();
            if(tmpabove != NULL) tmpabove->next_row = newnode;
            if(tmpleft != NULL) tmpleft->next_col = newnode;
            else{
                    tmpaboveleft = newnode;
                    tmpleft = newnode;
            }
            tmpabove = tmpabove->next_col;
            tmpleft = tmpleft->next_col;
    }
    tmpabove = tmpaboveleft;

}}

void display_matrix(MatrixNode* head){
  MatrixNode *temp = head;

    while(temp != NULL){
    printf("%d", temp->val);
    temp = temp->next_col;
    }
    temp = temp->next_row;




}

SAMPLE OUTPUT:

./a.out 3   3   
Matrix  A   
66          39          33  
13          94          15  
94          64          23  

Upvotes: 1

Views: 9090

Answers (3)

BLUEPIXY
BLUEPIXY

Reputation: 40155

easy way like this:

void create_linked_list_matrix(MatrixNode **head, const int rows, const int cols){
    MatrixNode *mat[rows][cols];//use malloc if the number of elements is large
    int r, c;
    for(r = 0; r < rows; ++r){
        for(c = 0; c < cols; ++c){
            mat[r][c] = create_node();
        }
    }
    for(r = 0; r < rows; ++r){
        for(c = 0; c < cols; ++c){
            if(c < cols -1)
                mat[r][c]->next_col = mat[r][c+1];
            if(r < rows -1)
                mat[r][c]->next_row = mat[r+1][c];
        }
    }
    *head = mat[0][0];
}

void display_matrix(MatrixNode *head){
    MatrixNode *row = head;
    while(row){
        MatrixNode *col = row;
        while(col){
            printf("%d\t", col->value);
            col = col->next_col;
        }
        printf("\n");
        row = row->next_row;
    }
}

reduced version

void create_linked_list_matrix(MatrixNode **head, const int rows, const int cols){
    MatrixNode *node, *mat[cols];
    int r, c;
    for(r = rows-1; r >= 0; --r){
        for(c = cols-1; c >=0; --c){
            node = create_node();
            if(r < rows -1)
                node->next_row = mat[c];
            mat[c] = node;
            if(c < cols -1)
                mat[c]->next_col = mat[c+1];
        }
    }
    *head = mat[0];
}

Upvotes: 1

eliotn
eliotn

Reputation: 300

  1. Look in create_linked_list_matrix. Do not use "new" as a variable name, because it is a reserved keyword. If you still want to call it that, you can always name it "new_" instead so it doesn't conflict with the reserved keyword.
  2. Also, that same function will create n+1 rows and columns due to how you set up your for loops. Try for (int i = 0; i < n; i++) if you want the loop to execute n times.
  3. In the same function, you aren't linking up your linked list properly. First, try nesting your for loops for rows and columns. Then, after you create a new node, remember to link the node to the left (if applicable) and the node above it. You will need to keep track of these nodes. Keep track of the node in the first column and row above so that you can point to the row above when you finish a row.

    MatrixNode *tmpabove = NULL, *tmpleft = NULL, *tmpaboveleft = NULL, *newnode = NULL;
    for(i = 0; i < rows; i++){
       tmpleft = NULL;
       for(y = 0; y < cols; y++){
          newnode = create_node();
          if (tmpabove != NULL) tmpabove -> nextrow = newnode;
          if (tmpleft != NULL) tmpleft -> nextcolumn = newnode;
          else {
             tmpaboveleft = newnode;
             tmpleft = newnode;
          }
          tmpabove = tmpabove -> nextcolumn;
          tmpleft = tmpleft -> nextcolumn;
       }
       tmpabove = tmpaboveleft;
    }
    

Upvotes: 0

sestus
sestus

Reputation: 1927

Ok lets have a closer look at your function.

Suppose that you create a new node using your create_node() fucntion.

new = create_node() //You state that new points to that new node.
new = new->next_row; //You state that new points to NULL again

As you can see, there is no connection between the one node and the next one. To solve this issue I would use a help pointer:

MatrixNode *new,*tmp = head;


new = create_node();
if (prev != NULL) { 
   prev->next = new;
   prev = prev->next;
}
else   //Means that this is the first element
   prev=new;

Change both for loops and ask if you need more help

Upvotes: 0

Related Questions