如何使用指针在C中以螺旋方式遍历矩阵



这是在Python中以螺旋方式遍历矩阵并将遍历打印为数组的算法:

def spiralTraverse(array):
result = []
startRow, endRow = 0, len(array) - 1
startCol, endCol = 0, len(array[0]) - 1

while startRow <= endRow and startCol <= endCol:
for col in range(startCol, endCol + 1):
result.append(array[startRow][col])

for row in range(startRow + 1, endRow + 1):
result.append(array[row][endCol])

for col in reversed(range(startCol, endCol)):
if startRow == endRow:
break
result.append(array[endRow][col])

for row in reversed(range(startRow + 1, endRow)):
if startCol == endCol:
break
result.append(array[row][startCol])

startRow += 1
endRow -= 1
startCol += 1
endCol -= 1

return result

因此,如果样本输入是

array = [[1, 2, 3, 4],[12, 13, 14, 5],[11, 16, 15, 6],[10, 9, 8, 7]]

输出将为

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]

我正试图用指针将其转换为C,但函数未能打印出最终的数组。该文件进行编译,但在spiralTraverse((中带有与多维数组相关的警告作为参数。我从main((调用spiralTraverse函数,如下所示:spiralTraverse(*array[r], r, c),其中r=rowsc=cols分别是行数和列数。

这就是我所做的:

void spiralTraverse(int *vector[], int rows, int cols)
{
int i, indx_col, indx_row;
int indx_array = 0;
int startRow = 0;
int endRow = rows-1;
int startCol = 0;
int endCol = cols-1;
int new_array[rows*cols];

while ((startRow <= endRow) && (startCol <= endCol))
{
for (indx_col=startCol;indx_col<endCol+1;indx_col++)
new_array[indx_array++] = *(*(vector+startRow)+indx_col);

for (indx_row=startRow+1;indx_row<endRow+1;indx_row++)
new_array[indx_array++] = *(*(vector+indx_row)+endCol);
for (indx_col=endCol;indx_col>startCol;indx_col--)
{
if (startRow == endRow)
break;
new_array[indx_array++] = *(*(vector+endRow)+indx_col);
}
for (indx_row=endRow;indx_row>startRow+1;indx_row--)
{
if (startCol == endCol)
break;
new_array[indx_array++] = *(*(vector+indx_row)+startCol);
}
startRow++;
endRow--;
startCol++;
endCol--;
}
puts("");
puts("The array below displays the elements in spiral order");
for (i=0;i<(rows*cols);i++)
printf("%d, ", new_array[i]);
puts("");
}
}

为什么程序无法打印我的最终一维数组?

函数参数

该文件进行编译,但在spiralTraverse()中带有与多维数组相关的警告作为参数。

请参阅其他问答;有关在C:中分配和传递多维数组作为函数参数的正确方法的详细信息

正确分配多维数组
What';VLA的意义何在
如何将多维数组传递给C和C++中的函数

给定阵列

int array[][4] = {
{ 1,  2,  3, 4},
{12, 13, 14, 5},
{11, 16, 15, 6},
{10,  9,  8, 7}
};

函数签名可能是之一

// Declaring m as a Variable Length Array (since C99, optional from C11)
void spiral_traverse(int rows, int cols, int m[rows][cols]);
// or as a pointer to arrays of size 4
void spiral_traverse(int rows, int *m[4]);

保持简单

该算法的C实现与循环的外部存在问题,特别是第二个和第三个:

for ( indx_row = startRow + 1; indx_row < endRow + 1; indx_row++ )
//                                      ^^^^^^^^^^^^
/* ... */ = *(*(vector+indx_row)+endCol);
for ( indx_col = endCol; indx_col > startCol; indx_col-- )
//    ^^^^^^^^^^^^^^^^^
/* ... */ = *(*(vector+endRow)+indx_col);

第一个(好吧,第二个(循环访问的最后一个元素是vector[endRow][endCol],它与另一个循环首先访问的相同。

以下版本将产生预期的输出。

注意,我改变了循环的极端。

#include <stdio.h>
void spiral_traverse(int rows, int cols, int m[rows][cols]);
int main(void)
{
int array[][4] = {
{ 1,  2,  3, 4},
{12, 13, 14, 5},
{11, 16, 15, 6},
{10,  9,  8, 7}
};
spiral_traverse(4, 4, array);
spiral_traverse(3, 4, array); // Elements are stored row-major.
}
void spiral_traverse(int rows, int cols, int m[rows][cols])
{ // m is a Variable Length Array        ^^^^^^^^^^^^^^^^^
int startRow = 0;
int endRow = rows - 1;
int startCol = 0;
int endCol = cols - 1;
int new_array[rows*cols]; // <-- Another VLA
int i = 0;
while ((startRow <= endRow) && (startCol <= endCol))
{
for (int col = startCol; col < endCol; ++col, ++i)
{ //                         ^              ^^^^^
new_array[i] = m[startRow][col];
} //               ^^^^^^^^^^^^^^^^      

for (int row = startRow; row < endRow; ++row, ++i)
{ //         ^^^^^^^^^^      ^              ^^^^^        
new_array[i] = m[row][endCol];
} //               ^^^^^^^^^^^^^^
for (int col = endCol; col > startCol; --col, ++i)
{ //         ^^^^^^^^      ^                ^^^^^           
new_array[i] = m[endRow][col];
} //               ^^^^^^^^^^^^^^
for (int row = endRow; row > startRow; --row, ++i)
{ //         ^^^^^^^^      ^                ^^^^^
new_array[i] = m[row][startCol];
} //               ^^^^^^^^^^^^^^^^
startRow++;
endRow--;
startCol++;
endCol--;
}
puts("nThe array below displays the elements in spiral order");
for (i=0;i<(rows*cols);i++)
printf("%d, ", new_array[i]);
putchar('n');
}

当然,如果目标只是打印元素,那么实际上不需要将所有元素复制到另一个数组中。此外,引入函数指针参数,函数可以变得更通用(例如,请参见此处(。

最新更新