正确在C中横向打印二叉树

时间:2018-12-17 18:57:18

标签: c binary-tree pretty-print

我一直在尝试使函数以一种漂亮的方式在控制台的侧面打印出一棵二叉树(在这种情况下是一棵红黑树)。我在互联网上找到了该算法,并将其修改为我的项目。

注意:在SO和其他网站上,我已经见过很多用Java打印二进制树的方法,但是它们大多使用Java的String或其他一些高级语言,而在C语言中,有时很难适应代码。下面的代码与我以漂亮的方式打印二叉树所获得的代码非常接近。

static void
rbt_display_treeview(Node *root, int depth, char *path, bool is_right)
{
    const int spaces = 8;

    if (root == NULL)
        return;

    depth++;

    rbt_display_treeview(root->right, depth, path, true);

    path[depth - 2] = 0;

    if(is_right)
        path[depth - 2] = 1;

    if(root->left)
        path[depth - 1] = 1;

    printf("\n");

    for (int i = 0; i < depth - 1; i++)
    {
        if (i == depth - 2)
            printf("%c", is_right ? 218 : 192);
        else if (path[i])
            printf("%c", 179);
        else
            printf(" ");

        for (int j = 1; j < spaces; j++)
            if (i < depth - 2)
                printf(" ");
            else
                printf("%c", 196);
    }

    printf(" %d\n", root->data);

    for (int i = 0; i < depth; i++)
    {
        if (path[i])
            printf("%c", 179);
        else
            printf(" ");

        for (int j = 1; j < spaces; j++)
            printf(" ");
    }

    rbt_display_treeview(root->left, depth, path, false);
}

上面的代码称为:

// Red-Black tree is created and elements (int) are added

// Printing the tree
char *path = calloc(10000, sizeof(char));

if (!path)
        return;

rbt_display_treeview(tree->root, 0, path, false);
printf("\n");
free(path);

但是有两个问题:当节点是根节点时,此代码将尝试访问-1的索引char *path,如果树确实是树,则可能会发生char *path的溢出真的很大。所以这是我的前两个问题:

  • 当节点为root时如何防止这种行为?
  • path应该有多大,以便如果用户尝试打印一棵真正的大树,他将在缓冲区溢出之前耗尽堆栈空间?

测试时,我在红黑树中按顺序添加了以下整数:

[ 16, -34, 24, 43, 18, 20, 22, -21, 4, 28, 45, 24, -47, -43, 29, 14, -35, 32, 8, -9, -46, 41, 46, -3, 17, -32, 24, 50, -19, -48, 15, 20, 22, -50, -43, 18, -28, 12, -14, 19, 12, 44, 19, 23, 45, -38, 45, -15, -28, 15, 35, 16, -41, -25, 7, -20, -7, -13, -31, -5, -48, -37, -23, -36 ]

它产生了以下输出:

                            ┌─────── 50
                            │
                    ┌─────── 46
                    │       │
                    │       └─────── 45
                    │               │
                    │               └─────── 44
                    │
            ┌─────── 43
            │       │
            │       │       ┌─────── 41
            │       │       │
            │       └─────── 35
            │               │
            │               └─────── 32
            │
    ┌─────── 29
    │       │
    │       │       ┌─────── 28
    │       │       │
    │       └─────── 24
    │               │
    │               │               ┌─────── 23
    │               │               │
    │               │       ┌─────── 22
    │               │       │       │
    │               └─────── 20
    │                       │
    │                       │       ┌─────── 19
    │                       │       │
    │                       └─────── 18
    │                               │
    │                               └─────── 17
    │
     16
    │
    │                               ┌─────── 15
    │                               │
    │                       ┌─────── 14
    │                       │       │
    │                       │       └─────── 12
    │                       │
    │               ┌─────── 8
    │               │       │
    │               │       │       ┌─────── 7
    │               │       │       │
    │               │       └─────── 4
    │               │               │
    │       ┌─────── -3
    │       │       │
    │       │       │               │       ┌─────── -5
    │       │       │               │       │
    │       │       │               ┌─────── -7
    │       │       │               │       │
    │       │       │       ┌─────── -9
    │       │       │       │       │
    │       │       │       │       └─────── -13
    │       │       │       │               │
    │       │       └─────── -14
    │       │               │
    │       │               │       ┌─────── -15
    │       │               │       │       │
    │       │               └─────── -19
    │       │                       │
    │       │                       └─────── -20
    │       │                               │
    └─────── -21
            │
            │                               ┌─────── -23
            │                               │
            │                       ┌─────── -25
            │                       │       │
            │               ┌─────── -28
            │               │       │
            │               │       │       ┌─────── -31
            │               │       │       │
            │               │       └─────── -32
            │               │               │
            │       ┌─────── -34
            │       │       │
            │       │       │               ┌─────── -35
            │       │       │               │
            │       │       │       ┌─────── -36
            │       │       │       │       │
            │       │       │       │       └─────── -37
            │       │       │       │
            │       │       └─────── -38
            │       │               │
            │       │               └─────── -41
            │       │
            └─────── -43
                    │
                    │       ┌─────── -46
                    │       │
                    └─────── -47
                            │
                            └─────── -48
                                    │
                                    └─────── -50

但是随后我看到了一些不应该打印的行,例如数字22、4,-7,-13,-15等下方的行。因此,我在最后一个for中添加了另一个条件循环查看是否可以过滤那些不必要的行:

for (int i = 0; i < depth; i++)
{
    if (path[i] && (root->left || i != depth -1)) /* Here */
        printf("%c", 179);
    else
        printf(" ");

    for (int j = 1; j < spaces; j++)
        printf(" ");
}

事实上确实如此,但是我仍然不知道为什么。同样,当节点-9上方的两行不应出现时,它们仍在打印。这是我到目前为止的内容:

                            ┌─────── 50
                            │
                    ┌─────── 46
                    │       │
                    │       └─────── 45
                    │               │
                    │               └─────── 44
                    │
            ┌─────── 43
            │       │
            │       │       ┌─────── 41
            │       │       │
            │       └─────── 35
            │               │
            │               └─────── 32
            │
    ┌─────── 29
    │       │
    │       │       ┌─────── 28
    │       │       │
    │       └─────── 24
    │               │
    │               │               ┌─────── 23
    │               │               │
    │               │       ┌─────── 22
    │               │       │
    │               └─────── 20
    │                       │
    │                       │       ┌─────── 19
    │                       │       │
    │                       └─────── 18
    │                               │
    │                               └─────── 17
    │
     16
    │
    │                               ┌─────── 15
    │                               │
    │                       ┌─────── 14
    │                       │       │
    │                       │       └─────── 12
    │                       │
    │               ┌─────── 8
    │               │       │
    │               │       │       ┌─────── 7
    │               │       │       │
    │               │       └─────── 4
    │               │
    │       ┌─────── -3
    │       │       │
    │       │       │               │       ┌─────── -5
    │       │       │               │       │
    │       │       │               ┌─────── -7
    │       │       │               │
    │       │       │       ┌─────── -9
    │       │       │       │       │
    │       │       │       │       └─────── -13
    │       │       │       │
    │       │       └─────── -14
    │       │               │
    │       │               │       ┌─────── -15
    │       │               │       │
    │       │               └─────── -19
    │       │                       │
    │       │                       └─────── -20
    │       │
    └─────── -21
            │
            │                               ┌─────── -23
            │                               │
            │                       ┌─────── -25
            │                       │
            │               ┌─────── -28
            │               │       │
            │               │       │       ┌─────── -31
            │               │       │       │
            │               │       └─────── -32
            │               │
            │       ┌─────── -34
            │       │       │
            │       │       │               ┌─────── -35
            │       │       │               │
            │       │       │       ┌─────── -36
            │       │       │       │       │
            │       │       │       │       └─────── -37
            │       │       │       │
            │       │       └─────── -38
            │       │               │
            │       │               └─────── -41
            │       │
            └─────── -43
                    │
                    │       ┌─────── -46
                    │       │
                    └─────── -47
                            │
                            └─────── -48
                                    │
                                    └─────── -50
  • 如何防止打印这两行?

P.S .:红黑树实现的工作方式与其他任何红黑树一样。您也可以在其他二进制树中对此进行测试,因为我希望此代码在任何二进制树上运行。

0 个答案:

没有答案