我正试着做一个函数,按照我教授的要求,以垂直的方式打印一棵二维二叉搜索树.但是,我无法计算在打印树的每一行时所需的适当间距.这反过来又会让它看起来一团糟.

下面是打印当前层的函数的循环/片段:

for (int i = 0; i < nodesInLevel; i++)
        {
            current = dequeue(q);

            if (current != NULL)
            {
                printf("%d", current->data);
                enqueue(q, current->left);
                enqueue(q, current->right);
            }
            else
            {
                printf(" ");
                enqueue(q, NULL);
                enqueue(q, NULL);
            }

            if (i < nodesInLevel - 1) {
                printSpaces(4);
            }
        }
    
        printf("\n");

很简单,我使用广度遍历来导航树并相应地打印每一行. 下一部分是混乱的地方. 我应该打印斜线来表示边缘. 这应该很容易.只需要打印一个新行,(如new函数中所示)然后根据子对象是否存在来打印斜线.

正在讨论的循环:

for (int i = 0; i < nodesInNextLevel; i++)
    {
        printSpaces(spaces  -   2);

        if (current == NULL)
        {
            printSpaces(2);
            continue;
        }

        if (current->left == NULL && current->right == NULL)
        {
            continue;
        }
        else if (current->left != NULL && current->right == NULL)
        {
            printSpaces(2);
            putchar('/');
        }
        else if (current->left == NULL && current->right != NULL)
        {
            printSpaces(3);
            putchar('\\');
        }else
        {
            printSpaces(2);
            putchar('/');
            printSpaces(2);
            putchar('\\');
        }
    }
        printf("\n");

这两个for循环都在具有以下变量的更大的for循环中执行:

for (int level = 1; level <= treeHeight; level++)
    {
        nodesInLevel = 1 << (level - 1);
        nodesInNextLevel = nodesInLevel;
        spaces = (1 << (treeHeight - level + 1) - 1);
...

现在,这可能是因为我缺乏使用二元运算符的经验.我只是直接使用chat gpt来初始化这些变量(我现在后悔这个 idea 了).

但出于某种原因,输出结果如下所示:

               5
                /  \
        3    45
        /  \        /  \
    2    4    25    105

而不是我想要的,那就是:

             5
            /  \
           3     45
         /  \   /  \
        2   4  25 105

在构思/起草计划的概念时,我如何修正我的计算,甚至如何继续进行这些计算.

不确定这是否算作MCVE: 但这里是指向我的代码的链接,我所有的函数、 struct 和头文件都存储在这里. https://gist.github.com/SalManRAMc/fa636355cc042df3868b630e19ba8c97

推荐答案

你没有发布可编译的代码,因此有原始的路由图.

如果树是平衡的,取树叶 node 的最大位数,比方说D.

行占位符的长度是(D + 1) * N,假设是L,其中N2^(tree depth + 1).

对于如下所示的每行输出 (L - N * (level node count)) / 2个空格,后跟(depth - level)个空格分隔的 node .

你会得到

      5
  3      45
2   4  25 105

当您实现并调试它时,继续前进:添加偶数行,类似于+1行,但 node 值只是备选的 /\ .

摘要: node 值最大长度为D,每个 node 取D + 1(值+页边距+空格分隔符),左首行对齐为最后一行长度/2减go node 大小,下一行左对齐为上一行的/2, node 间相似间距相应计算.你可以在这里看到一些数学printTree(),这里的数学可以帮助,尽管它是C++.

C++相关问答推荐

不同到达时间的轮询实现

需要大整数和浮点数.使用long long int和long double

丑陋的三重间接:可扩展的缓冲区管理 struct

在没有动态内存分配的情况下,用C语言最快地将各种数组复制到单个较大的数组中

为什么GCC C23中的关键字FALSE不是整数常量表达式?

为静态库做准备中的奇怪行为

实现简单字典时C语言中的段错误

错误:包含文件时类型名称未知

如何将另一个数组添加到集合中,特别是字符串?

编译器如何处理具有更复杂值的枚举?

变量的作用域是否在C中的循环未定义行为或实现定义行为的参数中初始化?

不同原型的危险C函数是可能的

Zlib:解压缩大文件导致";无效代码长度设置";错误

如何将两个uint32_t值交织成一个uint64_t?

有没有办法减少C语言中线程的堆大小?

即使客户端不发送数据,也会发生UNIX套接字读取

free后内存泄漏?

malloc:损坏的顶部大小无法找出问题

用于内存布局的size命令(文本、数据、bss)

K&R 练习 1-24