簡體   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