Why isn't my printLevel function working? - c++

I have written this code to do level order traversal of Binary Search tree. Error is only in printLevel function because all other functions are working fine.
#include <queue>
using namespace std;
struct node{
int data;
struct node* left;
struct node* right;
};
struct node* newNode(int data){
struct node* node = new (struct node);
node->data=data;
node->left=NULL;
node->right=NULL;
return (node);
};
struct node* insert (struct node* node, int data){
if (node==NULL){
return (newNode(data));
}
else {
if (data<=node->data) node-> left=insert(node->left,data);
else node->right=insert(node->right,data);
return (node);
}
}
void printLevel(struct node* node){
queue<struct node*> q;
while(node!=NULL){
cout << node->data << " ";
q.push(node->left);
q.push(node->right);
node=q.front();
}
}
int main(){
int n;
cin >>n;
int m;
cin >>m;
struct node* root=newNode(m);
for (int i=0;i<n-1;i++){
cin>>m;
insert(root,m);
}
printLevel(root);
// printPostOrder(root);
// cout <<maxDepth(root);
// debug(maxDepth(root), minValue(root), printTree(root));
//struct node* root=build123();
}
Here is the algorithm: (http://www.geeksforgeeks.org/level-order-tree-traversal/)
printLevelorder(tree)
1) Create an empty queue q
2) temp_node = root /start from root/
3) Loop while temp_node is not NULL
a) print temp_node->data.
b) Enqueue temp_node’s children (first left then right children) to q
c) Dequeue a node from q and assign it’s value to temp_node
I am taking input 3,1,4,2,7,6,5 for 7 nodes. It gets stuck in infinite loop. I have also implemented following two functions based on another method and it is working fine:
void levelOrder(struct node* node, int level ){
if (node==NULL){
return;
}
if (level==1){
cout << node->data;
}
else if (level>1){
levelOrder(node->left,level-1);
levelOrder(node->right,level-1);
}
}
void printLevelOrder(struct node* root){
for (int i=1;i<=maxDepth(root);i++){
levelOrder(root,i);
}
}
It is O(n^2) but above one is O(n). What's wrong with my code? Thanks.

I suspect that your loop termination is wrong.
Instead of node != NULL, you should check to see if !q.empty().
Also, the call q.front does not remove the element from the queue; to do that, you need pop (after calling front).
This code works for me:
void printLevel(struct node* node){
std::queue<struct node*> q;
q.push(node);
while(!q.empty()) {
node=q.front();
q.pop();
if ( node != NULL ) {
std::cout << node->data << " ";
q.push(node->left);
q.push(node->right);
}
}
}

Related

How to get all values smaller than a given key in a BST?

Hello I am implementing a binary search tree. I have to find all the elements smaller than a given key applying a binary search:
struct node {
int data;
node* right;
node* left;
};
class binTree {
public:
binTree();
~binTree();
void insert(node**, int);
void inOrder(node**)const;
void preOrder(node**)const;
void postOrder(node**)const;
void delTree();
node* search(node**, int)const;
void search_less(node**, int)const;
};
binTree::binTree() {
}
binTree::~binTree() {
}
void binTree::insert(node** root, int data) {
node* tmp = *root;
if (!tmp) {
tmp = new node;
tmp->data = data;
tmp->right = NULL;
tmp->left = NULL;
*root = tmp;
return;
}
if (data < tmp->data)
insert(&tmp->left, data);
else
insert(&tmp->right, data);
}
void binTree::preOrder(node** root)const {
node* tmp = *root;
if (tmp) {
cout << tmp->data << endl;
preOrder(&tmp->left);
preOrder(&tmp->right);
}
}
void binTree::inOrder(node** root)const {
node* tmp = *root;
if (tmp) {
inOrder(&tmp->left);
cout << tmp->data << endl;
inOrder(&tmp->right);
}
}
void binTree::postOrder(node** root)const {
node* tmp = *root;
if (tmp) {
postOrder(&tmp->left);
postOrder(&tmp->right);
cout << tmp->data << endl;
}
}
node* binTree::search(node** root, int data)const {
node* tmp = *root;
if (tmp) {
if (data == tmp->data) {
cout << "found!" << endl;
return tmp;
}
else
if (data < tmp->data)
search(&tmp->left, data);
else
search(&tmp->right, data);
}
cout << data << ": not found in tree!" << endl;
return NULL;
}
void binTree::search_less(node** root, int key)const
{
node* tmp = *root;
tmp = search(root, key);
}
int main()
{
node* root = NULL;
binTree bt;
bt.insert(&root, 42000);
bt.insert(&root, 41000);
bt.insert(&root, 45000);
bt.insert(&root, 47000);
bt.insert(&root, 42500);
bt.insert(&root, 43000);
bt.insert(&root, 44000);
bt.insert(&root, 40000);
bt.insert(&root, 10000);
bt.insert(&root, 20000);
bt.insert(&root, 30000);
bt.search_less(&root, 42000); // I want to get values smaller than 42000
}
I've tried too much but couldn't figure it out. I want to print all the values below the key entered. Thank you.
Create an accumulator std::vector<T>
Set root node as current node
If current node is nullptr, go to 6 (you're done)
If current node is >= search value, set left node as current node and go to 3
If current node is < search value, accumulate this value and accumulate the entire subtree of the left node. Set right node as current node and go to 3
Return the accumulator
Accumulating the entire left node should be its own function (accumulate_entire_tree or something like that). The recursive function should be steps 3-5. Steps 1-6 are the entire wrapper function. In the end you get three functions:
std::vector<int> search_less_than(const Node& root, int key) const
void accumulate_less_than(const Node* root, int key, std::vector<int>& accumulator) const
void accumulate_entire_tree(const Node* root, std::vector<int>& accumulator) const
Make the last two functions private since they're more implementation details than interface.
You can make something similar to your search function:
void binTree::search_less(node** root, int data) const {
node* tmp = *root;
if (tmp) {
if (data > tmp->data) {
search_less(&tmp->left, data);
cout << tmp->data << endl;
search_less(&tmp->right, data);
} else {
search_less(&tmp->left, data);
}
}
}
Demo
In case the Key is existing then it is straightforward: inside search_less use yur function search to find the key then pass its node to inOrder or postOrder...
If the you want to get values smaller than a non existing key: It is a bit tricky:
If the key is smaller than the root node data then move leftward until data is smaller than the key or equal then pass that node to inOrder or postOrder.
If the key is greater than root then move rightward until a node with data is smaller than or equal to it then do the first step and print.
void binTree::search_less(node** root, int data)const
{
node* tmp = *root;
if (tmp && tmp->data < data)
tmp = tmp->right;
while (tmp && tmp->data >= data)
tmp = tmp->left;
inOrder(&tmp);
}
I've spent some considerable time and effort to find this solution on my own:
void binTree::search_less(node** root, int key)const
{
node* tmp = *root;
if(tmp)
{
search_less(&tmp->left, key);
if(key <= tmp->data)
return;
search_less(&tmp->right, key);
std::cout << tmp->data << ", ";
}
}
int main()
{
node* root = NULL;
binTree bt;
bt.insert(&root, 42000);
bt.insert(&root, 41000);
bt.insert(&root, 45000);
bt.insert(&root, 47000);
bt.insert(&root, 42500);
bt.insert(&root, 43000);
bt.insert(&root, 44000);
bt.insert(&root, 40000);
bt.insert(&root, 10000);
bt.insert(&root, 20000);
bt.insert(&root, 30000);
bt.search_less(&root, 37500);
std::cout << "\nDone!\n";
}
The output:
30000, 20000, 10000,
Done!
[Process completed - press Enter]
I walk left most through recursion until i get to the smallest value in the tree using the "inOrder" method because it get values sorted from small to big. then print it and walk right and check whether the data is greater than or equal to the key, in this case stop and return.
Please tell me whether this is a correct and efficient solution?

I can't figure out the reason for abnormal termination while executing levelOrder function?

This code is for Implementing binary tree.
It consist of insertNode(function which inserts node in the tree) and levelOrder(function which traverse the binary tree at level order).
insertNode function works fine but while executing levelOrder it successfully displays the data but after that it stops working and displays program has stopped working.
I can't find where i am going wrong?
Thanks in advance{ : )
#include<iostream>
using namespace std;
struct Node
{
Node *left;
Node *right;
int data;
}*root;
struct Queue
{
Node *p[1000];
int index=-1;
Node *add(Node *ptr)
{
p[++index]=ptr;
return ptr;
}
Node *peek()
{
if(index==-1)
return NULL;
return p[0];
}
Node *pop()
{
if(index==-1)
return NULL;
Node *temp=p[0];
for(int i=0;i<index;i++)
p[i]=p[i+1];
index--;
return temp;
}
};
Node * createNode(int data)
{
Node *p=new Node();
p->data=data;
p->left=p->right=NULL;
return p;
}
///////Insertion Of Node////////
int insertNode(int val)
{
if(root==NULL)
{
root=createNode(val);
return val;
}
bool found=false;
Node *p;
Queue q;
q.add(root);
while(found==false)
{
Node *l=(q.peek())->left;
Node *r=(q.peek())->right;
if(l==NULL)
{
(q.peek())->left=createNode(val);
found=true;
return val;
}
else
q.add(l);
if(r==NULL)
{
q.peek()->right=createNode(val);
found=true;
return val;
}
else
q.add(r);
q.pop();
}
return val;
}
/////////Traversal's///////////
void levelOrder(Node *p)
{
if(p==NULL)
return;
Queue q;
q.add(p);
while(true)
{
cout<<q.peek()->data<<" ";
if(q.peek()->left!=NULL)
q.add(q.peek()->left);
if(q.peek()->right!=NULL)
q.add(q.peek()->right);
if(q.pop()==NULL)
return;
}
}
int main()
{
root=NULL;
insertNode(1);
insertNode(2);
insertNode(3);
insertNode(4);
levelOrder(root);
return 0;
}
After you have popped the last element from the queue, you q.peek()->data on the next iteration, when q.peek() is not a valid pointer.
Change your termination condition:
while (q.peek())
{
cout<<q.peek()->data<<" "<< endl;;
if(q.peek()->left!=NULL)
q.add(q.peek()->left);
if(q.peek()->right!=NULL)
q.add(q.peek()->right);
q.pop();
}
On a side note, this is one situation where a "loop-local" variable can improve readability - all those peeks add clutter:
while(Node *next = q.pop())
{
cout<<next->data<<" "<< endl;;
if(next->left != nullptr)
q.add(next->left);
if(next->right != nullptr)
q.add(next->right);
}

Binary Search Tree leaf count issue

I desperately need help finding the problem in my code, I'm sure it's narrowed down to the countLeaves function. I can't seem to get it to print out no matter how I alter it. I'm pretty new to C++ but I'd really appreciate anything anyone can offer me! I will post the header, function, and main in that order.
#include <iostream>
//#include<stack>
//#include<queue>
#ifndef BSTFunction
#define BSTFunction
using namespace std;
typedef int num;
class Node{
public:
num info;
Node* left;
Node* right;
Node(); // Valuetype to num
Node(num);
};
class BST{
public:
Node* findNode(num);
Node* findParent(num);
Node* findrightnode(Node*);
void inorder(Node*);
Node* root;
Node* curr;
//Was public:
BST();
void insert(num);
void inorderTraversal(); //was traverse
num search();
void custom_print();
int countLeaves(Node* T);
};
#endif
Function.cpp
#include <iostream>
#include <queue>
#include "BSTFunction.hpp"
Node::Node(){
left=right=NULL;
}
Node::Node(num val){
info=val;
left=right=NULL;
}
//constructor
BST::BST(){
root=curr=NULL;
}
//insert a node with value val in tree
void BST::insert(num val){
if(root==NULL)
root = new Node(val);
else{
Node* p =findNode(val);
if(p==0) {
//cout<<"fine1";
Node* parent=root;
if (p != root)
parent = findParent(val);
if(val>parent->info) parent->right=new Node(val);
else parent->left=new Node(val);
}//cout<<"fine2";
}
}
//remove the node if value is val
//fins node with a value key
Node* BST::findNode(num key){
Node* p =root;
while((p!=NULL)&&(p->info!=key)){
if(key<p->info)p=p->left;
else p=p->right;
}
return p;
}
//find parent of a node with value key
Node* BST::findParent(num key){
Node* p =root;
Node* q=0;
while((p!=NULL)&&(p->info!=key)){
q=p;
if(key<p->info)p=p->left;
else p=p->right;
}
return q;
}
//finds the most right of a node p(means immediate succesor of p in inorder representation)
//Node* BST::findrightnode(Node* p){
// Node* righty=p;
// while(righty->right!=NULL)
// righty=righty->right;
// return righty;
//}
void BST::inorder(Node* p){
if(p!=NULL){
inorder(p->left);
cout<<p->info<<" ";
inorder(p->right); }
}
void BST::inorderTraversal(){
cout<<endl<<"Inorder: ";
inorder(root);
cout<<endl;
}
//to print tree hightwise i.e. all nodes at h1, then all nodes at h2, then at h3
void BST::custom_print(){
//Node* temp;
if(root==NULL)
return;
queue<Node*> Q;
Q.push(root);
//Q.push(NULL);
while(!Q.empty()){
curr=Q.front();
cout<<curr<<" ";
Q.pop();
Q.push(curr->left);
Q.push(curr->right);
}
}
int BST::countLeaves(Node *T)
{
if(T ==NULL) //if T is empty, return0
{
return(0);
}
else if(T -> left == NULL && T-> right == NULL) //if T has0 children, then it is a leaf
{
return(1);
}
else
{
return countLeaves(T -> left) + countLeaves(T -> right); //recursive call to find more leaves
}
}
Main.cpp
#include<iostream>
#include "BSTFunction.hpp"
int main()
{
BST leaves;
leaves.insert(24);
leaves.insert(43); //The code will take all of these numbers entered into the main function and put them in traversal order, much like it could under any order (post or pre) if needed. (Note to self: Not needed for this assignment)
leaves.insert(82);
leaves.insert(22);
leaves.insert(12);
leaves.insert(92);
leaves.insert(68);
leaves.insert(20);
leaves.insert(4);
cout << "These are the in order leaves for the Bianary Search Tree. " << endl;
leaves.inorderTraversal();
cout << "The number of leaves are: " << endl;
leaves.countLeaves()
//leaves.custom_print();
return 0;
}
The problem in your code is that you have an argument in your countLeaves() function-
int BST::countLeaves(Node *T)
When you call this function from your main, it doesn't have an
argument to give to countLeaves(). It throws an error as it doesn't
receive any parameter.
As for the solution, you'll have to create a Node object in your main and send it as an argument. You'll have to worry about what and how you are going to do all this. There seems to be a few errors both in logic and syntax. (I commented your countLeaves() call and it threw many errors.
Recommend using debugger.
Try to print values and "Function entered" print statements to make it easier to find mistakes in your program if you cannot use debugger at the moment.
Hope this was helpful.

why is the root value not being updated

This is the code to find the ceil and floor in BST. When I am trying to insert the data. every time the insert call goes to the first if condition. i.e. though I pass the pointer. The value is not being updated in the main function. can some one tell me why is it so?
using namespace std;
struct Node
{
int key;
struct Node* right;
struct Node* left;
};
struct Node* newNode(int key)
{
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
newNode->right = NULL;
newNode->left = NULL;
newNode->key = key;
return newNode;
}
void insert(struct Node** root,int key) {
if((*root) == NULL){
(*root)= newNode(key);
cout<<"entered first if condition"<<endl;
}
else if( (*root)->key <= key)
insert(&((*root)->left),key);
else
insert (&((*root)->right),key);
}
int ceil( struct Node* root , int input)
{
if (root == NULL)
return -1;
if(root->key == input)
return root->key;
if(root->key < input)
return ceil( root->right , input);
else{
int ceilnum = ceil(root->left, input);
return (ceilnum >= input) ? ceilnum : root->key;
}
}
int main()
{
int size, temp, ceilfor;
struct Node* root = NULL;
cout<< "size" << endl;
cin >> size;
for( int i = 0; i< size; i++)
{
cin >> temp;
insert(&root,temp);
}
cout<< root->key;
cout<< root->left->key;
cout << root->right->key;
cout << "ceil for" << endl;
cin >> ceilfor;
cout<< ceil(root, ceilfor) <<endl;
}
It has to come to the first condition (either directly or indirectly through recursive calls).
The actual insertion happens only in the first if block and other blocks will recursively reach the first if block.

How to find the minimal element of a BST?

I'm a beginner to c++ and am having problems with finding the minimal element of a BST. The BST is implemented in this way:
class Tree{
struct Node {
int Element;
Node *Left, *Right;
Node(int Element) : Element(Element), Left(0), Right(0){}
};
Node *Root;
void InOrder(void(*Action)(int&), Node *Current);
void Destroy(Node *Current);
public:
Tree() : Root(0){}
void Insert(int Element);
void InOrder(void(*Action)(int&)) {InOrder(Action,Root);}
void Destroy() {Destroy(Root);}
};
The InOrder, Destroy and Insert methods are implemented like this:
void Tree::Insert(int Element) {
Node *NewElement = new Node(Element);
if(!Root) Root = NewElement;
else {
Node *Previous, *Current = Root;
while(Current) {
Previous = Current;
if(Element < Current->Element) Current = Current->Left;
else Current = Current->Right;
}
if(Element < Previous->Element) Previous->Left = NewElement;
else Previous->Right = NewElement;
}
}
void Tree::InOrder(void(*Action)(int&),Node *Current) {
if(Current) {
InOrder(Action,Current->Left);
Action(Current->Element);
InOrder(Action,Current->Right);
}
}
void Tree::Destroy(Node *Current) {
if(Current) {
Destroy(Current->Left);
Destroy(Current->Right);
delete Current;
}
}
And the main function and function which I use to print the numbers look like this:
void Print(int &e) {
cout << e << endl;
}
int main() {
Tree t;
while(1) {
int Number;
cout << "Insert number (insert 0 to end): ";
cin >> Number;
if(Number == 0) break;
t.Insert(Number);
}
t.InOrder(Print);
t.Destroy();
getch();
}
As you may noticed, the InOrder method is implemented also, maybe it can be used in some way to help solve my problem... Sorry for my bad English :/
The minimal value would be the first value that calls Action in the above code. Go left as far as you can, and the minimal value you shall find...