是否有O(n)方法在C中绘制二维阵列网格而不是O(n²)?

时间:2014-04-24 19:14:26

标签: c arrays algorithm big-o

是否有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");
}

3 个答案:

答案 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)。这些都不能改进。