How to create a binary tree and print the tree with a pretty‑printer that draws branches in C++

2 Answers

0 votes
#include <iostream>
#include <vector>
#include <string>
#include <memory>
 
struct Node {
    int value;
    std::unique_ptr<Node> left;
    std::unique_ptr<Node> right;
 
    explicit Node(int v) : value(v), left(nullptr), right(nullptr) {}
};
 
/* -------------------- Insert (BST) -------------------- */
 
void insert(std::unique_ptr<Node>& root, int value) {
    if (!root) {
        root = std::make_unique<Node>(value);
        return;
    }
    if (value < root->value) {
        insert(root->left, value);
    } else {
        insert(root->right, value);
    }
}
 
/* -------------------- Pretty Print --------------------
   Draws the tree horizontally using ASCII art.
-------------------------------------------------------- */
 
std::vector<std::string> buildLines(const Node* root) {
    if (!root) return {};
 
    std::string val = std::to_string(root->value);
 
    auto leftLines  = buildLines(root->left.get());
    auto rightLines = buildLines(root->right.get());
 
    int leftWidth  = leftLines.empty()  ? 0 : static_cast<int>(leftLines[0].size());
    int rightWidth = rightLines.empty() ? 0 : static_cast<int>(rightLines[0].size());
 
    std::string line1;
    std::string line2;
 
    if (!leftLines.empty() && !rightLines.empty()) {
        line1 += std::string(leftWidth, ' ');
        line1 += val;
        line1 += std::string(rightWidth, ' ');
 
        line2 += std::string(leftWidth - 1, ' ');
        line2 += "/";
        line2 += std::string(val.size(), ' ');
        line2 += "\\";
        line2 += std::string(rightWidth - 1, ' ');
    } else if (!leftLines.empty()) {
        line1 += std::string(leftWidth, ' ');
        line1 += val;
 
        line2 += std::string(leftWidth - 1, ' ');
        line2 += "/";
    } else if (!rightLines.empty()) {
        line1 += val;
        line1 += std::string(rightWidth, ' ');
 
        // FIXED: use std::string for concatenation
        line2 += std::string(" ");
        line2 += "\\";
        line2 += std::string(rightWidth - 1, ' ');
    } else {
        return { val };
    }
 
    std::vector<std::string> merged;
    merged.push_back(line1);
    if (!line2.empty()) merged.push_back(line2);
 
    int maxHeight = std::max(leftLines.size(), rightLines.size());
    for (int i = 0; i < maxHeight; ++i) {
        std::string leftPart  = i < static_cast<int>(leftLines.size())
            ? leftLines[i]
            : std::string(leftWidth, ' ');
        std::string rightPart = i < static_cast<int>(rightLines.size())
            ? rightLines[i]
            : std::string(rightWidth, ' ');
        merged.push_back(leftPart + std::string(val.size(), ' ') + rightPart);
    }
 
    return merged;
}
 
void printPretty(const Node* root) {
    auto lines = buildLines(root);
    for (const auto& line : lines) {
        std::cout << line << "\n";
    }
}
 
/* -------------------- Main -------------------- */
 
int main() {
    std::unique_ptr<Node> root = nullptr;
 
    insert(root, 8);
    insert(root, 3);
    insert(root, 10);
    insert(root, 1);
    insert(root, 6);
    insert(root, 14);
    insert(root, 4);
    insert(root, 7);
 
    printPretty(root.get());
}
 
 
/*
run:
 
     8    
    / \   
 3    10  
/ \    \ 
1  6    14
  / \     
  4 7       
 
*/
 

 



answered Sep 5 by avibootz
0 votes
#include <iostream>
#include <string>
#include <vector>
//#include <algorithm>

struct treenode {
    int data;
    treenode *left = nullptr;
    treenode *right = nullptr;
};

/* -------------------- Insert (BST) -------------------- */

void insert(treenode *&root, int value) {
    if (!root) {
        root = new treenode{value};
        return;
    }
    if (value < root->data) insert(root->left, value);
    else insert(root->right, value);
}

/* -------------------- Pretty Print --------------------
   Draws the tree horizontally using ASCII art.
-------------------------------------------------------- */

std::vector<std::string> buildLines(const treenode *root) {
    if (!root) return {};

    std::string val = std::to_string(root->data);

    auto leftLines  = buildLines(root->left);
    auto rightLines = buildLines(root->right);

    int leftWidth  = leftLines.empty()  ? 0 : leftLines[0].size();
    int rightWidth = rightLines.empty() ? 0 : rightLines[0].size();

    std::string line1;
    std::string line2;

    if (!leftLines.empty() && !rightLines.empty()) {
        line1 += std::string(leftWidth, ' ') + val + std::string(rightWidth, ' ');
        line2 += std::string(leftWidth - 1, ' ') + "/" +
                 std::string(val.size(), ' ') + "\\" +
                 std::string(rightWidth - 1, ' ');
    }
    else if (!leftLines.empty()) {
        line1 += std::string(leftWidth, ' ') + val;
        line2 += std::string(leftWidth - 1, ' ') + "/";
    }
    else if (!rightLines.empty()) {
        line1 += val + std::string(rightWidth, ' ');
        line2 += std::string(" ") + "\\" + std::string(rightWidth - 1, ' ');
    }
    else {
        return { val };
    }

    std::vector<std::string> merged;
    merged.push_back(line1);
    merged.push_back(line2);

    int maxHeight = std::max(leftLines.size(), rightLines.size());
    for (int i = 0; i < maxHeight; ++i) {
        std::string leftPart  = i < leftLines.size()  ? leftLines[i]  : std::string(leftWidth, ' ');
        std::string rightPart = i < rightLines.size() ? rightLines[i] : std::string(rightWidth, ' ');
        merged.push_back(leftPart + std::string(val.size(), ' ') + rightPart);
    }

    return merged;
}

void printPretty(const treenode *root) {
    auto lines = buildLines(root);
    for (const auto &line : lines) {
        std::cout << line << "\n";
    }
}

/* -------------------- Main -------------------- */

int main() {
    treenode *root = nullptr;

    insert(root, 8);
    insert(root, 3);
    insert(root, 10);
    insert(root, 1);
    insert(root, 6);
    insert(root, 14);
    insert(root, 4);
    insert(root, 7);

    printPretty(root);
}



/*
run:

     8    
    / \   
 3    10  
/ \    \ 
1  6    14
  / \     
  4 7     

*/

 



answered Sep 5 by avibootz
...