我正在尝试将数组转换为链表矩阵。如果我的输入是:
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 Matrixn");
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 Inputn");
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;
}
}
不错的锻炼。我有一个使用静态指针矩阵方法的解决方案。您可以以相同的方式动态分配它,但只是为了获得一个想法。
所以,我们开始了:
#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 Matrixn");
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 Inputn");
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;
}
}
ptr->down在您的情况下始终为NULL。它从不被初始化。所以col=col->down将值NULL分配给col
这项任务对初学者来说并不容易。
对于初学者来说,当使用像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) )