I'm trying to display a BST in console. That's my code (it's a modified version of code found here: Printing Level Order Binary Search Tree Formatting):
string printLevel(node *root, int level, string gap) {
if (!root) {
return gap + "-" + gap;
}
if (level==1) {
stringstream out;
out<<root->value;
return gap + out.str() + gap;
} else if (level>1) {
string leftStr = printLevel(root->left, level-1, gap);
string rightStr = printLevel(root->right, level-1, gap);
return leftStr + " " + rightStr;
} else return "";
}
void printLevelOrder (node* root, int depth) {
for (int i=1; i<=depth; i++) {
string gap="";
for (int j=0; j<pow(2,depth-i)-1; j++) {
gap+=" ";
}
string levelNodes = printLevel(root, i, gap);
cout<<levelNodes<<endl;
}
}
For example result should be like that:
4
1 6
- 2 5 -
- - - 3 - - - -
But instead it is:
4
1 6
- 2 5 -
- - 3 - - -
If I undestand correctly, the recursion stops when the program makes it to the empty leaf and therefore there are lacking " - " on the lower levels in the result. But how do I know how much of those I should draw on the lower levels? How to make this work?
I instrumented the code to see where it went awry (since running a debugger in a browser...), you can see it live here. The reproduced function is:
string printLevel(node *root, int level, string gap) {
if (root == 0) {
cout << ".. printLevel - " << root << ": " << gap << "-" << gap << "\n";
return gap + "-" + gap;
}
if (level==1) {
stringstream out;
out<<root->value;
cout << ".. printLevel - " << root << ": " << gap << root->value << gap << "\n";
return gap + out.str() + gap;
} else if (level>1) {
string leftStr = printLevel(root->left, level-1, gap);
string rightStr = printLevel(root->right, level-1, gap);
cout << ".. printLevel - " << root << ": '" << leftStr << "', '" << rightStr << "'\n";
return leftStr + " " + rightStr;
} else return "";
}
And here is the bit of interesting output:
.. printLevel - <none>: -
.. printLevel - <none>: -
.. printLevel - { 3, <none>, <none> }: 3
.. printLevel - { 2, <none>, { 3, <none>, <none> } }: '-', '3'
.. printLevel - { 1, <none>, { 2, <none>, { 3, <none>, <none> } } }: '-', '- 3'
So, the issue is that you short-circuit whenever root
is 0, which is actually an issue: -
is not the right output unless level
is 1
.
The only difference between root
being 0 and root
not being 0 is that you cannot read the value out of it (and thus get to replace it by -
); however you only really read that value when level
is 1
(beware, you might try to read left
or right
too), therefore there is no reason to test for root == 0
unless you are in the level == 1
branch.
Let us slightly reorder things then:
string printLevel(node *root, int level, string gap) {
if (level==1) {
// if (root == 0) {
// cout << ".. printLevel - " << root << ": " << gap << "-" << gap << "\n";
// return gap + "-" + gap;
// }
stringstream out;
out<<root->value;
cout << ".. printLevel - " << root << ": " << gap << root->value << gap << "\n";
return gap + out.str() + gap;
} else if (level>1) {
// string leftStr = printLevel(root ? root->left : 0, level-1, gap);
// string rightStr = printLevel(root ? root->right : 0, level-1, gap);
cout << ".. printLevel - " << root << ": '" << leftStr << "', '" << rightStr << "'\n";
return leftStr + " " + rightStr;
} else return "";
}
Note: I "highlighted" the modified lines with "comments".
And now, the tree prints properly.
void BinaryTree::Display(TreeNode *current, int indent)
{
if (current != nullptr)
{
Display(current->left, indent + 4);
if (indent > 0)
cout << setw(indent) << " ";
cout << current->value << endl;
Display(current->right, indent + 4);
}
}
prints tree left to right instead of top down.
1
2
3
4
5
6
7
8
12
18
Here is my code. It prints very well,maybe its not perfectly symmetrical.
little description:
- 1st function - prints level by level (root lv -> leaves lv)
- 2nd function - distance from the beginning of new line
- 3rd function - prints nodes and calculates distance between two prints;
void Tree::TREEPRINT()
{
int i = 0;
while (i <= treeHeight(getroot())){
printlv(i);
i++;
cout << endl;
}
}
void Tree::printlv(int n){
Node* temp = getroot();
int val = pow(2, treeHeight(root) -n+2);
cout << setw(val) << "";
prinlv(temp, n, val);
}
void Tree::dispLV(Node*p, int lv, int d)
{
int disp = 2 * d;
if (lv == 0){
if (p == NULL){
cout << " x ";
cout << setw(disp -3) << "";
return;
}
else{
int result = ((p->key <= 1) ? 1 : log10(p->key) + 1);
cout << " " << p->key << " ";
cout << setw(disp - result-2) << "";
}
}
else
{
if (p == NULL&& lv >= 1){
dispLV(NULL, lv - 1, d);
dispLV(NULL, lv - 1, d);
}
else{
dispLV(p->left, lv - 1, d);
dispLV(p->right, lv - 1, d);
}
}
}
Input:
50-28-19-30-29-17-42-200-160-170-180-240-44-26-27
Output: https://i.stack.imgur.com/TtPXY.png