I'm learning data structures on my own because they don't teach electrical engineers that stuff in school. I want to have a tool to print the rows of a tree so I can see what I'm traversing as I debug. Here's my iterative solution for printing a row, finding everything in the next row, and repeating. I feel like I should be doing this recursively but don't know how to get an output of rows, and I'd also like to make it easier to read than the left aligned output this produces. I'd also like to avoid adding a parent field to my tree nodes. Any advice?
void printtree(ibtreenode * root){
binodqueue * printbuff = new binodqueue;
binodqueue * searchbuff = new binodqueue;
printbuff->enqueue(root);
int row = 0;
while(!printbuff->isempty()){
ibtreenode * current = printbuff->dequeue();
if(current->left!=NULL)
searchbuff->enqueue(current->left);
if(current->right!=NULL)
searchbuff->enqueue(current->right);
printf(" %d ",current->data);
if(printbuff->isempty()){
printf("-- row %d\n",row);
row++;
while (!searchbuff->isempty()){
printbuff->enqueue(searchbuff->dequeue());
}
}
}
}
For reference: binodqueue
is a queue which holds and returns binary tree nodes and ibtreenode
is the name of my binary tree nodes holding ints.
Basic idea is to print the tree by traversing DFS and writing each node into a line of text. Putting some sort of prefix for each node below the root node ensures a visible structure.
The recursion is pretty basic...
code:
// print whatever you deem adequate as prefix before a node for a given level in the tree
void printprefix(int level) {
for (int i = 0; i < level - 1; ++i)
printf(" ");
if (level > 0)
printf("- ");
}
// recursive tree printing function
void printtree(ibtreenode * root, int level = 0){
// recursion anchor
if (root == NULL)
return;
// print current level
printprefix(level);
printf("%d\n",current->data);
// recurse sub-tree
printtree(root->left, level + 1);
printtree(root->right, level + 1);
}
Code might contain stupid syntax errors, since I have no C++ compiler at hand while writing this.
If you want nicely formatted visual output you could also decide to write your tree to a file and then use some tool like https://graphviz.org/ to convert the output to an actual image. If you are interested in an approach to write an input file for the graphviz dot format, I could expand my answer.
I would first recursively build a vector of rows, each row being a vector of pairs data - position_in_the_tree. This part is easy with an in order traversal of the tree.
Then I would use that vector to print each row knowing the position of the node in the tree .
Code could be:
// recursively builds the vector of rows
void buildrows(ibtreenode* root,
std::vector < std::vector<std::pair<int, unsigned> > >& rows,
unsigned & pos, unsigned level) {
if (root == nullptr) return;
if (level >= rows.size()) { // need to add a new row
rows.push_back(std::vector<std::pair<int, unsigned> >());
}
buildrows(root->left, rows, pos, level + 1);
std::pair<int, unsigned> p{ root->data, pos++ }; // here is pos handling
rows[level].push_back(p);
buildrows(root->right, rows, pos, level + 1);
}
/* root is the tree to print, width is the width used to print a value */
void printtree(ibtreenode* root, size_t width) {
std::vector < std::vector<std::pair<int, unsigned> > > rows;
unsigned pos = 0; // the position in the tree
buildrows(root, rows, pos, 0);
for (auto& row : rows) {
pos = 0;
for (auto& it : row) {
unsigned delta = 1 + it.second - pos;
std::cout << std::setw(delta * width) << it.first ;
pos = it.second + 1;
}
std::cout << '\n';
}
}
With a trivial tree I could get (with width
= 2):
4
2 6
1 3 5 7
and (after removing the 5 node):
4
2 6
1 3 7
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.