橫向打印二叉樹


問題描述

二叉樹可以用於排序。其原理很簡單:對於一個排序二叉樹添加新節點時,先與根節點比較,若小則交給左子樹繼續處理,否則交給右子樹。

當遇到空子樹時,則把該節點放入那個位置。

比如,10 8 5 7 12 4 的輸入順序,應該建成二叉樹如下圖所示,其中.表示空白。

...|-12
10-|
...|-8-|
.......|...|-7
.......|-5-|
...........|-4

本題目要求:根據已知的數字,建立排序二叉樹,並在標准輸出中橫向打印該二叉樹。

輸入格式

輸入數據為一行空格分開的N個整數。 N<100,每個數字不超過10000。

輸入數據中沒有重復的數字。

輸出格式

輸出該排序二叉樹的橫向表示。為了便於評卷程序比對空格的數目,請把空格用句點代替:

樣例輸入1
10 5 20
樣例輸出1
...|-20
10-|
...|-5
樣例輸入2
5 10 20 8 4 7
樣例輸出2
.......|-20
..|-10-|
..|....|-8-|
..|........|-7
5-|
..|-4
 
其實就是按照 右子樹 根 左子樹的順序遍歷,每個輸出占一行,寫一個遞歸遍歷的函數,traversal(BST *node,int h),h是空白的位數,當然空白中可能也有'|',對於結點node先遍歷
它的右子樹即最先輸出的,node和他的右子樹之間是豎線連接的,即他們之間這些行每行相同位置都是’|‘取代'.',一共多少行(node右子樹的左子樹結點總數),后面左子樹的情況類似。不過這里右子樹的情況需要加個判斷,因為遍歷是從node右子樹的右子樹開始。num記錄行數,tar記錄這個判斷條件也就是node的右結點Data,只有比這個值小才滿足。
 
代碼:
#include <iostream>
#include <cstdio>
#include <map>
#include <cstring>
#include <vector>
#include <algorithm>

using namespace std;
struct BST {
    int Data,l,r;
    BST *Left = NULL,*Right = NULL;
    BST(int d) {
        Data = d;
        l = 0,r = 0;///記錄左子樹結點個數以及右子樹的  后面遍歷用到
    }
}*head;
int num[2000];
int tar[2000];
BST* Insert(BST *h,int d) {
    if(h == NULL) {
        h = new BST(d);
    }
    else if(d < h -> Data) {
        h -> Left = Insert(h -> Left,d);
        h -> l ++;
    }
    else {
        h -> Right = Insert(h -> Right,d);
        h -> r ++;
    }
    return h;
}
int nc(int d) {
    int c = 0;
    while(d) {
        c ++;
        d /= 10;
    }
    return c;
}
void traversal(BST *node,int h) {///中序遍歷  右 中 左
    if(node == NULL) return;
    int ht = nc(node -> Data);///h是上層空白的個數,ht記錄這一層的數字占的空間那么下一層需要輸出的空白就是h + ht
    if(h) ht += 2;///不是根  數字前要輸出 |-   所以這是兩個位
    if(node -> Left || node -> Right) ht ++;///有子樹需要輸出 -|  豎線重合不算在內
    if(node -> Right) {
        num[h + ht] += node -> Right -> l;///右子樹的左子樹的結點個數 表示 后面在輸出右子樹的左子樹的時候h + ht位置不輸出'.'而是輸出'|'
        tar[h + ht] = node -> Right -> Data;///因為這中間情況會先遍歷右子樹的右子樹 為了避免提前輸出'|'所以設置當Data小於tar時才輸出
        traversal(node -> Right,h + ht);
    }
    for(int i = 0;i < h;i ++) {
        if(num[i] && (tar[i] == 10001 || node -> Data < tar[i])) {
            putchar('|');
            num[i] --;
        }
        else putchar('.');
    }
    if(h) printf("|-");
    printf("%d",node -> Data);
    if(node -> Left || node -> Right) printf("-|");
    putchar('\n');
    if(node -> Left) {
        num[h + ht] += node -> Left -> r;
        tar[h + ht] = 10001;///跟前面不同
        traversal(node -> Left,h + ht);
    }
}
int main() {
    int d;
    while(~scanf("%d",&d)) {
        head = Insert(head,d);
    }
    traversal(head,0);
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM