繁体   English   中英

以树格式打印二进制堆,C 语言

[英]Printing binary heap in tree format, C language

我制作了一个整数数组(代码中的mat ),它具有堆二叉树属性,因此第 i 个节点具有leftChild = i*2+1rightChild = i*2+2

如果第 i 个节点是 NULL 则mat[i] = -1 这是我写的一点打印 function:

int pos = 0, e = 0;
for( int i=0; i<n; i++ ) { // n = arr length

    if( mat[i] == -1 ) 
        printf(" ");
    else
        printf("%d  ", mat[i]);


    if( pos == 0 ) {
        pos = Power(2, e); // returns 2^e
        e++;
    }
    
    if( pos == 1 ) 
        printf("\n");

    pos--;
}

如果 arr = {15, 5, 19, 1, 14, -1, 254, -1, 3, 13, -1, -1, -1, 240, 360}

15  
5  19  
1  14   254  
 3  13     240  360  

我尝试了更好的格式,但我只到此为止:

    15  
   5  19  
  1  14   254  
  3  13     240  360

我知道一个可行的解决方案是构建一个矩阵,但我认为可能会有不同的答案,你有什么建议吗?

我设法写了以下内容:

#include <stdio.h>
#include <stdint.h>
#include <stddef.h>
#include <assert.h>
#include <stdbool.h>

static int pow2i(int a) {
    int r = 1;
    while (a--) {
        r *= 2;
    }
    return r;
}

static void display_tree(const int *arr, size_t arrlen) {
    assert(arrlen);

    int longest_digits = 0;
    int tree_depth = 0;

    int pos = 0;
    int depth = 0;
    for (size_t i = 0; i <arrlen; ++i) {
        if (arr[i] != -1) {
            const int len = snprintf(NULL, 0, "%d", arr[i]);
            if (longest_digits < len) {
                longest_digits = len;
            }
        }
        
        if (pos == 0) {
            tree_depth++;
            pos = pow2i(depth++);
        }
        pos--;      
    }

    //printf("%d %d\n", longest_digits, tree_depth);

    pos = 0;
    depth = 0;
    const int additional_offset = 3;
    int max_width = pow2i(tree_depth) * (longest_digits + additional_offset);
    for (size_t i = 0; i < arrlen; ++i) {
        const bool first = pos == 0;
        if (first) {
            pos = pow2i(depth);
            depth++;
        }
        const int count_elems = pow2i(depth);
        const int chunk = max_width / count_elems;
        const int width = chunk + (first ? -chunk/2 : 0);
        const int pre_spaces = width - longest_digits;

        printf("%*s", pre_spaces, "");
        if (arr[i] == -1) {
            printf("%*s", longest_digits, "-");
        } else {
            printf("%*d", longest_digits, arr[i]);
        }

        if (pos == 1) {
            printf("\n");
        }
        pos--;
    }

}

int main() {
    assert(pow2i(0) == 1);
    assert(pow2i(1) == 2);
    assert(pow2i(3) == 2*2*2);
    int arr1[] = {15, 5, 19, 1, 14, -1, 254, -1, 3, 13, -1, -1, -1, 240, 360};
    display_tree(arr1, sizeof(arr1)/sizeof(*arr1));
}

代码输出:

                      15
           5                      19
     1          14           -         254
  -     3    13     -     -     -   240   360

我重用了您的索引,但将单字母未知变量e重命名为更有意义的depth 首先,我计算树中所有数字的以 10 为底的最长位数,并找到最大树深度。 知道了这一点,我可以计算每个深度的树的宽度并计算每个深度的增量:

            xxx            - depth = 1
        xxx       xxx      - depth = 2
      xxx  xxx  xxx  xxx   - depth = 3

    |-------------------| - width of the whole tree
    |---------|           - offset to first number
     ----|---------|----  - positions at depth=2
    |----|----|----|----| - chunks sizes at depth=3

从中您可以计算在每个位置之间插入所需的空格数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM