是否有O(n)方法在C中绘制二维阵列网格而不是O(n²)?例如,我想知道是否有办法使用一个for
循环而不是两个循环。我总觉得有办法,但我想我会把它交给你......
ARRAY2D grid;
void ShowGrid(void)
{
int x, y;
for (y = 0; y < grid.height; y++)
{
for (x = 0; x < grid.width; x++)
{
printf("%d", arr2_get(&grid, x, y));
}
printf("\n");
}
printf("\n");
}
答案 0 :(得分:3)
您通常会研究在增加元素数量时会发生什么。
如果是这种情况,您发布的代码是O(N),而不是O(N 2 )。
如果网格有100个元素,printf
将被调用的次数将与100(O(N))成比例,与10,000不成比例(O(N 2 ))。
如果在另一个句柄上你正在研究当你增加行数或列数时会发生什么,访问所有元素将至少为O(R * C),因为你有R * C元素。
请注意,您可以展平这两个循环,但它至少不会改变复杂性:
void ShowGrid()
{
const int H = grid.height;
const int W = grid.width;
int n;
for (n = 0; n < H*W; ++n)
{
int y = n / W;
int x = n % W;
printf("%d", arr2_get(&grid, x, y));
printf("\n") if x == W-1;
}
}
答案 1 :(得分:2)
以下代码使用单个for
循环:
void ShowGrid(void)
{
int i;
for (i = 0; i < grid.width * grid.height; i++)
{
int x = i % grid.width;
int y = i / grid.width;
printf("%d", arr2_get(&grid, x, y));
if (x == grid.width - 1)
printf("\n");
}
printf("\n");
}
没有乘法或除法的另一种方法:
void ShowGrid(void)
{
int x = 0;
int y = 0;
while (y < grid.height) {
printf("%d", arr2_get(&grid, x, y));
x += 1;
if (x == grid.width) {
printf("\n");
x = 0;
y += 1;
}
}
printf("\n");
}
但时间复杂度显然与两个for
循环相同。
答案 2 :(得分:0)
有两种方法可以将2d矩阵构造为1维数组或循环变量,这将允许您使用1循环。但是,这根本不会减少运行时复杂性。
在您的情况下,您始终必须访问2D网格的每个单元格。
如果定义N =宽度*高度。你的代码已经是O(n)了。如果定义N = Width = Height,则代码为O(N ^ 2)。这些都不能改进。