Hello guys I am stack somewhere so this is my question...
I got the following binary tree class
public class BTree
{
private TreeNode root;
int i = 0;
/////////////////////
public BTree()
{
root = null;
}
}
and my TreeNode class
public class TreeNode
{
private TreeNode left; //consider public
private int number; //
private TreeNode right; //////////////////
//////////////////////
public TreeNode(int number)
{
this.number = number;
left = null;
right = null;
}
....
}
and I need to build a method that could count Tree height till a specific data
inside a Node. For Example: int height = tree.height(5);
(to find the height of the Node that contains number 5)
I am in the part :
public int height(int number)
{
return countHeight(root, number);
}
private int countHeight(TreeNode node, int number)
{
if(node != null && node.getNumber() == number)
return 0;
return //what should I write here?
}
Recursive methods is a little hard for me so I would like
a little help over here.
Thnx in advance...
I just wrote this code and it seems to work properly.
If you got any better solution feel free to share.
public int height(int number) /// it could be Object
{
return countHeight(root, number);
}
private int countHeight(TreeNode node, int number)
{
if(node != null && node.getNumber() == number)
return 1;
if(number < node.getNumber())
return countHeight(node.getLeft()) + 1;
else
return countHeight(node.getRight()) + 1;
}
Related
I have implemented a tree using classes in C++, but the program is not showing any output when I called display function. Can anyone spot the reason?
Output
#include<iostream>
using namespace std;
class TreeNode //node for tree
{
public:
int data;
TreeNode* left;
TreeNode* right;
TreeNode(int val)
{
data=val;
left=NULL;
right=NULL;
}
};
class Tree //class for tree
{
public:
TreeNode *r;
Tree()
{
r=NULL;
}
void insert(int data)
{
TreeNode* new_node=new TreeNode(data);
TreeNode*trav=r;
while(trav!=NULL)
{
if(data>trav->data)
{
if(trav->right==NULL)
{
trav->right=new_node;
break;
}
trav=trav->right;
}
else
{
if(trav->left==NULL)
{
trav->left=new_node;
break;
}
trav=trav->left;
}
}
}
void display()
{
print(r);
}
void print(TreeNode *node)
{
if(node!=NULL)
{
print(node->left);
cout<<node->data<<" ";
print(node->right);
}
}
};
int main() //main function
{
Tree T;
T.insert(10);
T.insert(1);
T.insert(2);
T.insert(100);
T.display();
}
At beginning, 'r' is not assigned, that is, 'r' is NULL pointer.
So In 'Insert' function, no values can be insert to Tree.
I think it is likely that the first input value is to be set as a default value. And then 'r' must be initialized at this point.
class Tree //class for tree
{
public:
TreeNode *r;
Tree()
{
r = NULL;
}
~Tree()
{
release(r);
}
void release(TreeNode * node)
{
if (node != NULL)
{
release(node->left);
release(node->right);
delete node;
node = NULL;
}
}
void insert(int data)
{
if (r == NULL)
{
r= new TreeNode(data);
return;
}
...
And you need to add logic to releasing the all memories allocated to 'r' in the destructor of the 'Tree' class.
Change the Tree constructor to something like this:
Tree(int root_data) {
r = new TreeNode(root_data);
r->left=NULL;
r->right=NULL;
}
And replace
Tree T;
with
int some_value;
Tree T(some_value);
I have been trying to get this function working for the longest time now. It is part of an assignment for an online course, but it seems no matter what I submit, the function fails for both the empty child test and the left child test. See code below. The main() function is deliberately commented out. Any info./input is much appreciated.
// C++ binary trees and stuff;
//
#include <iostream>
#include <cstdio>
#include <string>
#include <vector>
using namespace std;
class BST
{
public:
int data;
BST *left;
BST *right;
//BST *root;
// BST() constructor
BST (int num)
{
data = num;
left = nullptr;
right = nullptr;
root = nullptr;
}
// constructors for root node(s), initializing as root when no values exist yet;
BST() : root (nullptr){}
BST (BST *rootNode) : root(rootNode){}
void insert (int value)
{
BST *newNode = new BST();
newNode = root;
if (root == nullptr)
{
root = new BST (value);
}
else
{
root->data = value;
}
// check if newNode's value equals the passed-in value:
if (value == root->data)
{
//cout << "\nWarning! Value already exists in tree, so nothing will be done.\n";
return;
}
// check if value is < or > newNode's value:
if (value <= root->data)
{
if (root->left == nullptr)
{
// make a new node as the left child of this node,
root->left = new BST(value);
}
else
{
// recursively call insert() on tree's left side,
root->left->insert(value);
}
}
else
{
if (root->right == nullptr)
{
// make a new node as the right child of this node,
root->right = new BST(value);
}
else
{
// recursively call insert() on tree's right side,
root->right->insert(value);
}
}
}
public:
BST *root;
};
/*
int main (int argc, char *argv[])
{
//...insert code here,
// create nodes,...
BST rootNode(5);
BST leftNode(4);
BST rightNode(6);
// connect the nodes to the tree via rootNode.left and rootNode.right,..
rootNode.left = &leftNode;
rootNode.right = &rightNode;
printf ("\nData (root) value = %i, rootNode.left = %i, and rootNode.right = %i\n",
rootNode.data, rootNode.left->data, rootNode.right->data);
cout << "\n\nHello, Solar System!\n";
return 0;
}
*/
Okay, here's my suggestion. You need to reformat your code. You need two classes. You need a BST, and you need a Node. The various methods to add/remove/traverse are part of the BST class. Nodes are just Nodes.
So:
class BST_Node {
public:
int value;
BST_Node * left = nullptr;
BST_Node * right = nullptr;
// Define constructors, etc.
};
class BST {
public:
BST_Node * root = nullptr;
BST_Node * insert(int value);
void insertNode(BST_Node *node);
void insertNodeBelow(BST_Node *nodeToInsert, BST_Node *startingNode);
};
BST_Node * BST::insert(int value) {
BST_Node * node = new BST_Node(value);
insertNode(node);
return node;
}
void BST::insertNode(BST_Node *node) {
if (node == nullptr) {
return;
}
if (root == nullptr) {
root = node;
}
else {
insertNodeBelow(node, root);
}
}
void BST::insertNodeBelow(BST_Node *node, BST_Node *startingNode) {
if (node == nullptr || startingNode == nullptr) {
return;
}
if (node->value < startingNode->value) {
if (startingNode->left != nullptr) {
insertNodeBelow(node, startingNode->left);
}
else {
startingNode->left = node;
}
}
else {
if (startingNode->right != nullptr) {
insertNodeBelow(node, startingNode->right);
}
else {
startingNode->right = node;
}
}
}
How this works... First, the logic of how to store nodes is in BST. Nodes don't care. Second, I made methods for either inserting a value or a node. Because I think that's handy. That should be fairly easy to understand.
The root node can be null, if so, then your inserted node is now root. Otherwise it calls the recursive insertion function. Now, you could simplify this a little, but I didn't want to get too clever.
So it's simple. We look to see where it belongs relative to the point we're at (initially the root). Either we go into the left branch or the right branch. But that branch could be empty, so you just plop it right in. If it's not empty, then you recurse.
I didn't test it.
I posted something yesterday and got some help to get started, and I feel like I am almost there now. I have created a BST, with the primary key as a name, and the secondary key as that persons weight. I have managed to finish everything I need except for searching for the lowest weight (secondary key). My method to search the minimum weight is a preorder traversal, and it outputs all of the weights correctly to the screen. What is the technique to go about for determining which is the lowest now? I've tried a few different if statements, and creating a minwt int, but am having no luck getting to work (I think it has something to do with the recursion). Anyways, here is the code. Any help, like always, is greatly appreciated. Thanks.
#include <iostream>
using namespace std;
class tNode
{
public:
string name;
int wt;
tNode *left, *right;
tNode()
{
left = right = 0;
}
tNode(string name, int wt, tNode *l = 0, tNode *r = 0)
{
this->name = name;
this->wt = wt;
left = l;
right = r;
}
};
class bSTree
{
public:
tNode *root;
bSTree()
{
root = 0;
}
bool add(string name, int wt)
{
tNode *temp = root, *prev = 0;
while (temp != 0)
{
prev = temp;
if (name < temp->name)
{
temp = temp->left;
}
else
{
temp = temp->right;
}
}
if (root == 0)
{
root = new tNode(name, wt);
}
else if (name < prev->name)
{
prev->left = new tNode(name, wt);
}
else if (name > prev->name)
{
prev->right = new tNode(name, wt);
}
else
{
return false;
}
return true;
}
void searchWeight(tNode* temp)
{
// DETERMINE LOWEST WEIGHT CONTAINED IN TREE
if (temp != 0)
{
cout << temp->wt << endl;
searchWeight(temp->left);
searchWeight(temp->right);
}
}
};
You need some temporary variables to hold the lowest weight and associated key. They need to be accessible outside of the scope of your searchWeight() function. For example:
#include <iostream>
using namespace std;
int lowest_weight = 999999; // Something sufficiently high
string lowest_weight_key;
class tNode
{
/*...*/
void searchWeight(tNode* temp)
{
// DETERMINE LOWEST WEIGHT CONTAINED IN TREE
if (temp != 0)
{
// if temp->wt is lower than lowest weight
// set lowest_weight equal to temp->wt
// and set lowest_weight_key equal to temp->name
cout << temp->wt << endl;
searchWeight(temp->left);
searchWeight(temp->right);
}
}
};
Now, just print out the values of lowest_weight and lowest_weight_key after calling searchWeight().
Just a simple BST to print numbers inorder. Couldn't figure out what I did wrong.
#include <iostream>
using namespace std;
class bst {
private:
bst* root;
bst* left;
bst* right;
int value;
public:
bst(const int& numb) : root(NULL), left(NULL), right(NULL) {
value = numb;
}
void insert(const int& numb) {
if (numb < value) {
if (left == NULL) {
left = new bst(numb);
left->root = left;
} else {
left->insert(numb);
}
} else if (numb > value) {
if (right == NULL) {
right = new bst(numb);
right->root = right;
} else {
left->insert(numb);
}
} else if (numb == value) {
cout << "duplicated value" << endl;
}
}
void inorder() {
if (left == NULL) cout << value << endl;
else left->inorder();
right->inorder();
}
};
int main() {
bst tree(5);
tree.insert(7);
tree.insert(1);
tree.insert(3);
tree.insert(2);
tree.insert(9);
tree.insert(10);
return 0;
}
Line 29 should read:
right->insert(numb);
where it currently reads:
left->insert(numb);
I highly recommend looking into gdb for solving situations like this.
inorder() should be:
if (left != NULL) left->inorder();
cout << value << endl;
if (right != NULL) right->inorder();
I assume the rest are correct.
Logic errors throughout.
Crash is here:
if (right == NULL) {
right = new bst(numb);
right->root = right;
} else {
left->insert(numb);
}
The else case shold use right, not left.
At least as I see it, your fundamental design is flawed. Although I realize many text books (and such) describe a tree as a recursive structure where each node has two sub-trees, I've never found that a very good way to design the code.
At least in my experience, in actual code, you're (much) better off separating the notion of a node in the tree from the notion of an entire tree. Only the tree should be visible to the outside world; node should be hidden away inside the tree, invisible to the outside world.
class bst {
class node {
int value;
node *left;
node *right;
// ...
};
// ...
node *root;
};
I'd then split insert into two pieces: a public function that takes a value, and just forwards to the second function with the root as the starting point. The second actually traverses the three and inserts the new item:
// public interface:
void insert(int v) {
insert(new node(v), root);
}
// private workhorse:
void insert(node *n, node *&pos) {
if (pos == NULL)
pos = n;
else if (n->value < pos->value)
insert(n,pos->left);
else if (n->value > pos->value)
insert(n,pos->right);
else
// duplicate value.
}
Likewise, inorder gets split into a public and private pair, with the public providing only an interface, and the private one doing all the real work:
// public interface:
void inorder() {
inorder(root);
}
// private worker
void inorder(node *n) {
if (n==NULL)
return;
inorder(n->left);
std::cout << n->value << endl;
inorder(n->right);
}
For what it's worth: yes, I have tested this code and it does work at least with the input you used in you main. It does have shortcomings though. For example, both insert and inorder traverse the tree recursively, so a large, badly imbalanced tree could lead to stack overflow. It's fairly easy to do insertion iteratively, but for real use you usually just switch to some sort of balanced tree instead.
I need to add an item to a binary tree given only the item to be added.
Here is the code I'm given:
void BinaryTree::add(Data * data) {
if (root == NULL) {
root = new BinaryTreeNode(data);
}
else {
root->add(data);
}
}
where root is a private variable of a BinaryTree defined as a BinaryTreeNode.
I need to implement a method:
void BinaryTreeNode::add(Data * data);
where a BinaryTreeNode is:
class BinaryTreeNode {
public:
Data * nodeData;
BinaryTreeNode * left;
BinaryTreeNode * right;
/**
* Constructor
*/
BinaryTreeNode(
Data * data,
BinaryTreeNode * left = NULL,
BinaryTreeNode *right = NULL
)
: nodeData(data), left(left), right(right)
{ }
// ...
I want to do this recursively, but I'm not positive how when you're only passed the data to be added.
My idea that doesn't work is:
void BinaryTreeNode::add(Data * newData) {
BinaryTreeNode * temp = this;
if (temp == NULL) {
temp->nodeData = newData;
} else {
if (newData->compareTo(nodeData) < 0) {
temp->left->add(newData);
} else {
temp->right->add(newData);
}
}
}
You are setting temp to this and then comparing it to NULL. this should never be NULL. You need to check if the left and right are NULL.
Well a binary tree, atleast how I know how to implement involves something like the following with two objects, one containing the the treenode object, and the other acting as an interface for the whole tree.
class cBinaryTree {
public:
bool insert(int inData);
//Other operations
private:
cBinaryTreeNode* root;
bool leftInsertion;
cBinaryTreeNode* getRoot() { return root; }
As you are comparing the actually value of the input data and placing it accordingly, this qualifies as a binary search tree. Then the insertion function can be written as
bool cBinaryTree::insert(int inData) {
//handle case if its first node.
cBinaryTreeNode *Parent = getInsertionNodePosition(getRoot(), inData);
cBinaryTreeNode *newNode = createNewNode(inData);
if(leftInsertion) //insert into left. add return statement
Parent->setLeftChild() = newNode;
else //insert into right
}
The recursive lookup function will be something like
cBinaryTreeNode* getInsertionNodePosition(cBinaryTreeNode* node,int inData) {
//Check left subtree and proceed from there.
if(inData < node->getData()) {
if(node->getLeftChild() == NULL) {
leftInsertion = true;
return node;
}
else {
node = node->getLeftChild();
return getInsertionNodePosition(node, inData);
}
}
//Similarly Check right subtree.
Hope this helps.