无法创建链接列表矩阵

时间:2020-04-25 09:35:03

标签: c arrays matrix linked-list

我正在尝试将数组转换为链接列表矩阵。如果我输入的是:

1 2 3
4 5 6
7 8 9

然后链接列表矩阵将是这种类型的

1 -> 2 -> 3 -> NULL
|    |    |
v    v    v
4 -> 5 -> 6 -> NULL
|    |    |
v    v    v
7 -> 8 -> 9 -> NULL
|    |    |
v    v    v
NULL NULL NULL

我尝试调试代码。我在col = col->down中遇到分段错误错误。但我无法理解此错误的原因。这是代码供您参考。

#include<stdio.h>
#include<stdlib.h>
typedef struct node
{
  int data;
  struct node *next;
  struct node *down;
}matrix;
matrix *start = NULL;
void insert();
void arrToMatrix();
void arrDisplay();
void matrixDisplay();
int a[10][10];
int r,c;
int main()
{
  int n;
  printf("1:Insert elements 2:Convert Array to Linked Matrix 3:Display Array 4:Display Linked Matrix\n");
 for(;;)
 {
   printf("Enter choice: ");
   scanf("%d",&n);
   switch(n)
   {
      case 1: insert();
      break;
      case 2: arrToMatrix();
      break;
      case 3: arrDisplay();
      break;
      case 4: matrixDisplay();
      break;
      default: printf("Wrong Input\n");
      exit(0);
   }
 }
 return 0;
}

void insert()
{
  int i,j;
  printf("Enter row: ");
  scanf("%d",&r);
  printf("\nEnter column: ");
  scanf("%d",&c);
  printf("Enter elements: \n");
  for(i=0;i<r;i++)
      for(j=0;j<c;j++)
        scanf("%d",&a[i][j]);
}
void arrDisplay()
{
  int i,j;
  printf("Array elements: \n");
  for(i=0;i<r;i++)
  {
    for(j=0;j<c;j++)
    {
      printf("%d ",a[i][j]);
    }
    printf("\n");
  }
}
void arrToMatrix()
{
  int i,j;
  matrix *ptr, *col, *row;
  ptr = malloc(sizeof(matrix));
  ptr->data = a[0][0];
  ptr->next = NULL;
  ptr->down = NULL;
  start = ptr;
  col = start;
  for(i=0;i<r;i++)
  {
    row = col;
    for(j=0;j<c;j++)
    {
      ptr = malloc(sizeof(matrix));
      ptr->data = a[i][j];
      ptr->next = NULL;
      ptr->down = NULL;
      if(row == col)
        row = ptr;
      else
      {
        while(row->next!=NULL)
          row = row->next;
        row->next = ptr;
      }
    }
    col = col->down;
  }
}

void matrixDisplay()
{
  matrix *row, *col, *ptr;
  col = start;
  while(col!=NULL)
  {
    row = col;
    while(row!=NULL)
    {
      printf("%d ",row->data);
      row = row->next;
    }
    printf("\n");
    col = col->down;
  }
}

3 个答案:

答案 0 :(得分:1)

很好的锻炼。我有一个使用指针静态矩阵的方法的解决方案。您可以以相同的方式动态分配它,但是只是为了获得想法。

所以,我们开始:

#include<stdio.h>
#include<stdlib.h>
typedef struct node
{
  int data;
  struct node *next;
  struct node *down;
} matrix;

matrix *start = NULL;

#define MAX_DIM 10

matrix ptrMatrix[MAX_DIM][MAX_DIM];

void insert();
void arrToMatrix();
void arrDisplay();
void matrixDisplay();

int a[MAX_DIM][MAX_DIM];
int r,c;

int main()
{
  int n;
 for(;;)
 {
   printf("1:Insert elements 2:Convert Array to Linked Matrix 3:Display Array 4:Display Linked Matrix\n");
   printf("Enter choice: ");
   scanf("%d",&n);
   switch(n)
   {
      case 1: insert();
      break;
      case 2: arrToMatrix();
      break;
      case 3: arrDisplay();
      break;
      case 4: matrixDisplay();
      break;
      default: printf("Wrong Input\n");
      exit(0);
   }
 }
 return 0;
}

void insert()
{
  int i,j;
  printf("Enter number of rows: ");
  scanf("%d",&r);
  printf("\nEnter number of columns: ");
  scanf("%d",&c);

  if(r >= MAX_DIM)
  {
      printf("\nNo more than %d rows please!\n");
      return;
  }

  if(c >= MAX_DIM)
  {
      printf("\nNo more than %d columns please!\n");
      return;
  }

  printf("\n Now enter the elements (%d number in total): \n", r*c);
  for(i=0;i<r;i++)
  {
      for(j=0;j<c;j++)
      {
        scanf("%d",&a[i][j]);
      }
  }
}
void arrDisplay()
{
  int i,j;
  printf("Array elements: \n");
  for(i=0;i<r;i++)
  {
    for(j=0;j<c;j++)
    {
      printf("%d ",a[i][j]);
    }
    printf("\n");
  }
}
void arrToMatrix()
{
  if(r<=0 || c <=0)
  {
      printf("Matrix is empty. Try again!\n");
      return;
  }

  int i,j;

  for(i=0;i<r-1;i++)
  {
      for(j=0;j<c-1;j++)
      {
        ptrMatrix[i][j].data = a[i][j];
        ptrMatrix[i][j].next = &ptrMatrix[i][j+1];
        ptrMatrix[i][j].down = &ptrMatrix[i+1][j];
      }

      ptrMatrix[i][c-1].data = a[i][c-1];
      ptrMatrix[i][c-1].next = NULL;
      ptrMatrix[i][c-1].down = &ptrMatrix[i+1][c-1];
  }

  for(j=0;j<c-1;j++)
  {
    ptrMatrix[r-1][j].data = a[r-1][j];
    ptrMatrix[r-1][j].next = &ptrMatrix[r-1][j+1];
    ptrMatrix[r-1][j].down = NULL;
  }

  ptrMatrix[r-1][c-1].data = a[r-1][c-1];
  ptrMatrix[r-1][c-1].next = NULL;
  ptrMatrix[r-1][c-1].down = NULL;

  start = &(ptrMatrix[0][0]);
}

void matrixDisplay()
{
  matrix *row, *col;
  col = start;
  while(col!=NULL)
  {
    row = col;
    while(row!=NULL)
    {
      printf("%d ",row->data);
      row = row->next;
    }
    printf("\n");
    col = col->down;
  }
}

答案 1 :(得分:0)

在您的情况下,

ptr-> down始终为NULL。它从未被初始化。所以col = col-> down会将NULL值分配给col

答案 2 :(得分:0)

对于初学者来说,分配任务并不容易。

对于初学者来说,当使用诸如start之类的全局变量并且函数定义取决于全局变量时,这是个坏主意。

例如,您不能在程序中定义多个矩阵。

在函数arrToMatrix中,您必须处理指向指针的指针。否则函数会更复杂,或者指针起始位置将不会更改,因为更改程序中的局部变量col和row不会影响指针起始位置上的i =。而且例如在此代码段中

  ptr = malloc(sizeof(matrix));
  ptr->data = a[i][j];
  ptr->next = NULL;
  ptr->down = NULL;
  if(row == col)
    row = ptr;

当i等于0且j等于0时,存在节点的冗余分配。

在函数的开头,应释放由头指针指向的当前矩阵。否则可能会导致内存泄漏,并且用户将无法使用其他数组重新分配矩阵。

因此,您需要再编写一个函数,以释放所有分配给当前矩阵的内存。

这里是一个演示程序,显示了如何实现这些功能。在程序中,有注释的功能matrixDisplay用于测试。您可以运行它而不使用非注释函数matrixDisplay来查看列表及其链接的定义方式。

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

typedef struct node
{
    int data;
    struct node *next;
    struct node *down;
} matrix;

void deleteMatrix( matrix **head )
{
    if ( *head != NULL )
    {
        for ( matrix *row = ( *head )->next; row != NULL; )
        {
            while ( row != NULL )
            {
                matrix *tmp = row;
                row = row->next;
                free( tmp );
            }

            row = ( *head )->down;

            if ( ( *head )->down != NULL )
            {
                ( *head )->down = row->down;
            }
        }

        free( *head );
        *head = NULL;
    }
}

void arrToMatrix( matrix **head, size_t m, size_t n, int a[m][n] )
{
    deleteMatrix( head );

    matrix **row = head;

    for ( size_t i = 0; i < m; i++ )
    {
        matrix **column = row;

        for ( size_t j = 0; j < n; j++ )
        {
            *column = malloc( sizeof( matrix ) );
            ( *column )->data = a[i][j];
            ( *column )->down = NULL;
            ( *column )->next = NULL;

            column = &( *column )->next;    
        }

        row = &( *row )->down;
    }

    row = head;

    for ( size_t i = 0; i + 1 < m; i++ )
    {
        matrix *column   = *row;
        matrix *next_row_column = ( *row )->down;

        for ( size_t j = 0; j < n; j++ )
        {
            column->down = next_row_column;
            column = column->next;
            next_row_column = next_row_column->next;
        }           

        row = &( *row )->down;
    }
}

void matrixDisplay( const matrix *head )
{
    for ( ; head != NULL; head = head->down )
    {
        for ( const matrix *column = head; column != NULL; column = column->next )
        {
            printf( "%2d ", column->data );
        }
        putchar( '\n' );
    }
}
/*
void matrixDisplay( const matrix *head )
{
    for ( ; head != NULL; head = head->down )
    {
        for ( const matrix *column = head; column != NULL; column = column->next )
        {
            printf( "%2d ( %p ): next( %p ), down( %p )  ", 
                     column->data, ( void * )column, ( void * )column->next, ( void * )column->down );
        }
        putchar( '\n' );
    }
}
*/
int main(void) 
{
    enum { N = 3 };
    int a[][N] = 
    {
        { 1, 2, 3 },
        { 4, 5, 6 },
        { 7, 8, 9 }
    };

    matrix *head = NULL;

    arrToMatrix( &head, N, N, a );

    matrixDisplay( head );
    putchar( '\n' );

    deleteMatrix( &head );

    return 0;
}

程序输出为

 1  2  3 
 4  5  6 
 7  8  9 

注释函数matrixDisplay的输出可能例如以以下方式显示。

 1 ( 0x558b577e7260 ): next( 0x558b577e7280 ), down( 0x558b577e72c0 )   2 ( 0x558b577e7280 ): next( 0x558b577e72a0 ), down( 0x558b577e72e0 )   3 ( 0x558b577e72a0 ): next( (nil) ), down( 0x558b577e7300 )  
 4 ( 0x558b577e72c0 ): next( 0x558b577e72e0 ), down( 0x558b577e7320 )   5 ( 0x558b577e72e0 ): next( 0x558b577e7300 ), down( 0x558b577e7340 )   6 ( 0x558b577e7300 ): next( (nil) ), down( 0x558b577e7360 )  
 7 ( 0x558b577e7320 ): next( 0x558b577e7340 ), down( (nil) )   8 ( 0x558b577e7340 ): next( 0x558b577e7360 ), down( (nil) )   9 ( 0x558b577e7360 ): next( (nil) ), down( (nil) )