Rotate Binary Tree - c++

I am trying to print a non static binary tree.
It does print but it rotates towards the left. I cant find a way to correct this and make it rotate upright. 5 is the root node. Code:
template <class dataType>
void displaybinarytree(BinaryTree <dataType> * p, int indent)
{
if(p != NULL) {
if(p->right()) {
displaybinarytree(p->right(), indent+4);
}
if (indent) {
cout << setw(indent) << ' ';
}
if (p->right()){
cout<<" /\n" << setw(indent) << ' ';
}
cout<< p->getData() << "\n ";
if(p->left()) {
cout << setw(indent) << ' ' <<" \\\n";
displaybinarytree(p->left(), indent+4);
}
}
}
Output:
Expected output:

A recursive approach doesn't play nice with a line-based output, where a line consists of items from multiple sub-trees.
You should switch to a breadth-first-traversal, where you create a working set per tree level. You may need to pre-compute the space requirements of lower tree levels in order to output the desired alignments in higher levels.
A little starting code that doesn't really display the tree as a tree, but at least displays each node in the correct line.
void displaybinarytree(BinaryTree <int> * p, int indent)
{
deque<BinaryTree<int>*> current;
deque<BinaryTree<int>*> next;
next.push_back(p);
while (!next.empty())
{
current.swap(next);
while (!current.empty())
{
BinaryTree<int>* node = current.front();
current.pop_front();
if (node->left)
{
next.push_back(node->left);
}
if (node->right)
{
next.push_back(node->right);
}
// instead of a single space, appropriate spacing is needed
cout << " " << node->data;
}
// instead of a single newline, appropriate spacing and connector characters / \ are needed
cout << endl;
}
}
See the in-code-comments for things that are missing from this code. I replaced your dataType by int and used primitive fields instead of getter functions, since it doesn't really matter to the concept.

If you want the top of the tree to appear at the top of the output, you must output it first - before its branches.
Your code outputs the right branch first, and it therefore appears at the top of the output:
// Outputs right branch:
if(p->right()) {
displaybinarytree(p->right(), indent+4);
}
if (indent) {
cout << setw(indent) << ' ';
}
if (p->right()){
cout<<" /\n" << setw(indent) << ' ';
}
// Outputs "current" node:
cout<< p->getData() << "\n ";
You need to switch the order: output the current node, then the branches.
Also, the slashes are in the wrong direction, and the indent changes need to be corrected. The left branch should be indented less rather than more.
Making just these changes at least gets the tree printed "top down". You will still find the branches are not printed next to each other - that requires a significantly more complex solution.

Related

How do I check if the program cout is empty?

I am facing a problem where I have a void function which prints out AVL tree node values using inorder traversal. However, I also need to print out "EMPTY" if the void function does not have any cout. And since the void function is recursive so I assume the cout << "EMPTY" << endl; can not be inside the function (Actually I tried but a lot of unncessary EMPTY were produced).My question is that is there any way I can check the program/function cout, something like: if(cout is empty){ print "EMPTY" }
void inorder(node* n){
if(n != NULL){
inorder(n->left);
cout << n->value << ' ';
inorder(n->right);
}
}
You can't query cout to find out whether it printed something or not. There actually is a method (tellp()) that returns the position of a std::basic_ostream stream (which is what cout is), but when called on cout is always returns -1, presumably because cout is not keeping track of the number of characters it has printed (aka its "position" within the output stream).
Therefore the only practical way to know if something was printed is to instrument your inorder() function to provide that information to the caller, via a return-value (as Retired Ninja suggests in the comments) or via some other mechanism (e.g. writing to a by-reference argument, or setting a global variable, or etc)
When you call inorder, it is guaranteed to produce some ouput if, and only if, its parameter is not NULL. So you can do this:
void inorderTraverse(node* n)
{
if (n == NULL)
std::cout << "EMPTY" << std::endl;
else
inorder(n);
}
Then, wherever you first call inorder, call inorderTraverse instead.
The way to do this is to have two functions:
one that the user calls, and which will print “EMPTY” if the tree is empty
one that does everything else
The common way to do this is with a “detail” namespace, but any other method for having a helper function would work as well:
namespace detail{
void inorder(node* n){
if(n != NULL){
inorder(n->left);
std::cout << n->value << ' ';
inorder(n->right);
}
}
}
void inorder(node* n){
if(n) detail::inorder(n);
else std::cout << "EMPTY";
}
Another common way of doing this is having an additional, defaulted-argument (boolean, in this case) to indicate whether or not it is a toplevel invocation:
void inorder(node* n, bool is_top=true){
if (n != NULL){
inorder(n->left, false);
std::cout << n->value << ' ';
inorder(n->right, false);
}else if(is_top){
std::cout << "EMPTY";
}
}
I personally do not like flaggy code, though — the helper function is an old, recognizable idiom and avoids the overhead of the boolean tests at every leaf node.

Simplify Do While Loop Checking for Null Pointer

I have a really basic problem that I can't figure out. I'm using chaining with hash tables to store nodes that collide with each other. I used a do while loop to print the first node at least once, and continue to print the chained nodes if they exist. However, in order to traverse the chained list, I need to change the address of the node for the next loop. Any way I try writing this, I find myself repeating code, which I was trying to avoid by using this loop. Please help
do {
cout << "Bid id: " << table.at(i)->bidId << " title: " << table.at(i)->title <<
" fund: " << table.at(i)->fund << " amount: " << table.at(i)->amount << endl;
if (table.at(i)->next!=nullptr){//check if first node has next node
table.at(i) = table.at(i)->next; //change address to the next pointer
}// how do I avoid repeating my condition below?
}
while (table.at(i)->next!=nullptr);
This code will replicate the functionality in your loop without duplicating the check against NULL.
while(true)
{
cout << /* stuff */ endl;
auto next = table.at(i)->next;
if(next)
table.at(i) = next;
else
break;
}
From the description though, are you sure you want to reassign the values inside your hash map while looping over them? I suspect that this code may suit your intent/needs better:
auto current = table.at(i);
while(current)
{
cout << /* stuff */ endl;
current = current->next;
}
When you find yourself in a situation like this one, it's a good idea to question your premise. In this case, I am talking about your assumption that you need a do while loop.
If there is a chance that your data won't be there or that your container is empty, then a do while won't do the job because it will loop at least once.
Generally, for iterating through a collection of data you'll want to use a for or while loop.
If I understand the code correctly, you need a precondition loop and not a postcondition one, as you have right now. For example:
while (table.at(i)) {
cout << "Bunch of stuff";
table.at(i) = table.at(i)->next;
}
You could try doing:
for(auto node = table.at(i)->next;node!=nullptr;node=node->next)
cout << "Bid id: " << node->bidId << " title: " << node->title;
Where you may need to replace node = table.at(i)->next with an appropriate way of getting a link to the first entry.
You can use C++11's range based for loop here. All you want to know is that value->next is not a nullptr before doing the assignment. Rest all is taken care by the simple and modern range based for loop
for(auto const& value: table) {
if (value->next != nullptr) {
value = value->next;
}
}
Its even faster and safer this way
If really you want to be able to get last element after the loop, you may do:
do {
cout << "Bid id: " << table.at(i)->bidId
<< " title: " << table.at(i)->title
<< " fund: " << table.at(i)->fund
<< " amount: " << table.at(i)->amount << endl;
if (table.at(i)->next == nullptr){
break;
}
table.at(i) = table.at(i)->next;
} while (true);
// table.at(i) != nullptr && table.at(i)->next == nullptr

Printing a binary tree with specified indent level in C++

I'm having trouble printing a binary tree. Basically each node contains two values - key and data. The problem is for this assignment,
I am expected to use double-space instead of \t. Basically it means, \t = 2 spaces, \t\t = 4 spaces, \t\t\t = 6 spaces
My problem is, I have implemented the printIndented method in the following way -
void
TreeDictionary::printIndented(TreeNode * node, int level) {
if (node == NULL)
return;
if (level == 0)
{
std::cout << node->_key << ':' << node->_data << "\n";
level++;
printIndented(node->_left, level);
printIndented(node->_right, level);
}
else
{
if ((node->_left == NULL) && (node->_right == NULL))
cout << '\t';
cout << "\t" << node->_key << ':' << node->_data << endl;
if ((node->_left != NULL) && (node->_right != NULL))
cout << '\t';
printIndented(node->_left, level);
if ((node->_left != NULL) && (node->_right != NULL))
cout << '\t';
printIndented(node->_right, level);
}
}
which is giving me an output as follows -
---=WHAT I AM GETTING=---
pineapple:0
kiwi:1
grapes:3
apple:5
orange:6
lime:8
olives:9
mango:10
strawberry:4
watermelon:7
---=EXPECTED OUTPUT=--- (as you see it prints 2 spaces instead of each \t)
pineapple:0
kiwi:1
grapes:3
apple:5
NULL
NULL
NULL
orange:6
lime:8
NULL
olives:9
mango:10
NULL
NULL
NULL
NULL
strawberry:4
NULL
watermelon:7
NULL
NULL
It seems like I am unable to account for the NULL values and print NULL whenever a NULL entry is found. All help is appreciated!
NOTE : The expected output is for default indent-level that is 0 for this program.
You're not really using the information that you're getting from knowing the level that you're at. Think of it as indenting from the left most edge of the screen. Per level you want to indent it by 2*level spaces. From the output, it looks like a NULL node prints out NULL. You could try something along the lines of:
Indent(Treenode *node, int level){
std::cout << std::string(2*level, ' ');
if(node == NULL){
std::cout << "NULL" << std::endl;
}else{
std::cout << node->_key << ":" << node->_data << std::endl;
level += 1;
Indent(node->_right, level);
Indent(node->left, level);
}
}
First of all, you should also check if the first node, at level 0, has childs. Else you could run into an error if there is only one node in your tree.
Second, I encourage you to use curling braces after the if statements, this is confusing and not very readable:
if((node->_left != NULL) && (node->_right != NULL)) {
cout << "\t"; //or in your case maybe: cout << " "; //see point 3
}
Third point, when you want to print a space instead of a '\t' you should do ' ' instead of '\t'. You also use "\t", which is the syntax for printing a string instead of a character, this is not wrong but I think you need to understand the principle. '\t' = const char, "\t" = const string
4th, I don't really understand what criterium you maintain for printing with different kind of indentation, so if you can explain what you are trying to accomplish with the if statements that would be great, then I can explain it to you as well.
If you have any questions left or you find this not helpfull just tell me :)
Good luck!

Comparing One Link List to Another Blacklist versus Word Frequency List C++

I have created a program that will read a text file and put the words as strings into a linked list, along with their frequency count throughout the text file. It only prints one occurrence of each word with the total times it appeared.
My program also loads a blacklist, in which it is supposed to compare the blacklist linked list to the word cloud (or word frequency) linked list, and then remove the blacklisted words from the word frequency list.
I have tried doing this several ways. The following is my 3rd version. What I am wanting to do is add a Boolean value to each node, and when one node is equal to a word in the blacklist, the Boolean value will be true. However, I am not getting it to print right with the following code. I have searched, and I can't seem to find the correct syntax to add a Boolean value to a node in linked list.
EDIT #3:
void wordCloud::compareWith(wordCloud& wordList, wordCloud& badList){
wordNode *wordListTemp, *blacklistTemp, *temp = NULL;
unsigned int counter = 0;
for (blacklistTemp = badList.head; blacklistTemp; blacklistTemp = blacklistTemp->next){
cout << blacklistTemp->myWord << "\n";
for (wordListTemp = wordList.head; wordListTemp; wordListTemp = wordListTemp->next){
if (wordListTemp->myWord != blacklistTemp->myWord){
wordListTemp->blacklist = false;
if (wordListTemp->blacklist = false){
cout << wordListTemp->myWord << " <"
<< wordListTemp->freq_count << ">\n";
}
}
else if (wordListTemp->myWord == blacklistTemp->myWord){
cout << blacklistTemp->myWord << " " << wordListTemp->myWord << "\n";
wordListTemp->blacklist = true;
if (wordListTemp->blacklist = true)
cout << wordListTemp->myWord << "\n";
}
}
//counter++;
cout << blacklistTemp->myWord << " " << wordListTemp->myWord << "\n";
}
system("pause");
}
This is not complete, but it is as far as I have gotten. The problem is it only prints the true if, and will not print any false if. Even if I switch the values, it will still only print the true if's. So I am assuming that I am going about this wrong. What would be the correct way to "flag" a node true and "flag" a node false? All the cout's are for debugging purposes. I will remove or comment those out later.
First of all, you could always debug step-by-step to see just which portion of the code freezes up your comp. The better way to detect memory leaks would be to use Valgrind.
On a side note, I would implement that comparison function as a comparison operator, and implement a comparison operator for their Nodes as well (for convenience). Doing so divides the code a bit and helps, later on, understand where your problem is. It is also a better way to do it (more readable, OOP-y, etc).
Finally!!
With a lot of old fashion debugging and cout statements, I finally got what I wanted. I know this might have been easy for some, but with not being very familiar with linked lists, this was quite the process for me.
Before I was trying to delete words that were seen in the blacklist linked list out of the wordList linked list. I decided later to just try to add a boolean value of true to the nodes in wordList, and then adjust my print function to not print nodes with the value of true. I also had to tweak a few things in insertWord(), and my freqSort() functions, but all that really consisted of was adding a pointer to the boolean value when a new node was being created.
My member function is void wordCloud::compareWith(wordCloud& wordList, wordCloud& badList), and is part of my wordCloud class. Here is the following definition:
void wordCloud::compareWith(const wordCloud& wordList, const wordCloud& badList){
wordNode *wordListTemp, *blacklistTemp;
unsigned int counter = 0;
//loop that advances wordListTemp
for (wordListTemp = wordList.head; wordListTemp; wordListTemp = wordListTemp->next){
blacklistTemp = badList.head;
//loop advances blacklistTemp - compares links in wordList to badList(blacklist)
//and sets the node to true if myWord equals any word in the blacklist
while (blacklistTemp){
if (wordListTemp->myWord == blacklistTemp->myWord){
wordListTemp->blacklist = true;
counter++;
}
blacklistTemp = blacklistTemp->next;
}
//for debugging
//cout << blacklistTemp->myWord << " " << wordListTemp->myWord << "\n";
}
/********************* All for debugging ***************************************
cout << "True:\n\n";
wordListTemp = wordList.head; //reset wordListTemp to head
while (wordListTemp){ //print blacklisted words from wordList
if (wordListTemp->blacklist == true){
cout << wordListTemp->myWord << " <"
<< wordListTemp->freq_count << ">\n";
}
wordListTemp = wordListTemp->next;
}
//prints total words blacklisted
cout << "There are " << counter << " blacklisted words.";
cout << "\n\nFalse:\n\n";
wordListTemp = wordList.head; //reset wordListTemp to head
counter = 0;
while (wordListTemp){ //print non-blacklisted words from wordList
if (wordListTemp->blacklist == false){
cout << wordListTemp->myWord << " <"
<< wordListTemp->freq_count << ">\n";
counter++;
}
wordListTemp = wordListTemp->next;
}
//prints total words not blacklisted
cout << "There are " << counter << " words that are not blacklisted.\n";
system("pause");
******************** End debugging *******************************************/
}
So basically this is a comparison function that flags nodes that are found in another list. Works well and tested with all other options.

Expression Tree printLevel() function

I am implementing a tree which is a Binary Expression Tree. The leaf nodes are numbers, non-leaf nodes are math operators. Succesfully implemented printInorder,PostOrder, PreOrder, evaluate. But stucked with the printLevel().
Here is my int main ()
int main()
{
EXTree myTree;
string tests[] = {"2.1*3.1+4.2", "(2.0+1.3)/1.4", "2.*(1.3+1.4)","1.2*(1.3+1.4/0.5)","1.2*(1.3+1.4/0.5)-4.4", "1.2*(1.3+1.4/0.5)- (9/3)"};
for (int i=0; i < 6; i++)
{
myTree.build (tests[i]);
myTree.printInorder();
myTree.printPreorder();
myTree.printPostorder();
myTree.printLevel(); //Starting from level = 0
cout << "Evaulating myTree = " << format(myTree.evaluate(),2) << endl;
myTree.removeAll(); // removes all the nodes
}
}
printLevel(); only prints the level of the tree given above and its initally 0.
and here is my printLevel function.
void EXTree:: printLevel()
{
queue<Node*> levelq;
levelq.push(root);
cout << "Current Level is: ";
while( levelq.size() > 0 )
{
Node *cur = levelq.front();
cout << cur->Root << " ";
levelq.pop();
if (cur->Left) levelq.push(cur->Left);
if (cur->Right) levelq.push(cur->Right);
}
cout << endl;
}
But I really didnt understand how to implement the printLevel. Appreciate for any help to clarify it.
I just implemented the inOrder algorith to my printLevel and tried to change it but still didnt get it.
Since you have no problem with recursion, this would work without queue:
void EXTree:: printLevel()
{
int currentLevel = 0;
if (root)
{
cout << "Current Level is: ";
printLevelHelper(root,currentLevel);
}
else
cout << "This BST is Empty\n";
}
// Declare a private method:
void EXTree:: printLevelHelper(Node* &n, int &currentLevel)
{
cout << currentLevel << ' ';
if (n->Left)
{
currentLevel++;
printLevelHelper(n->Left,currentLevel);
currentLevel--;
}
if (n->Right)
{
currentLevel++;
printLevelHelper(n->Right,currentLevel);
currentLevel--;
}
}
When using Breadth First Search to print the nodes on one level immediately adjacent to each other, you'd just observe when the leftmost child of the leftmost node on the current level pops out of the queue: this must be the start of the next level. I could easily write the code but I'd guess it would incomprehensible for you and this homework is for you (I think you want to label your post appropriately as homework, BTW). Most of your implementation looks like a straight forward implementation. The only thing missing is detecting that the next level is reached.