Binary Tree findHeight - c++

So I'm trying to add a findHeight method to my professors Binary Tree Class, and I'm having a bit of trouble.
BTNode<T> findParent(BTNode<T> Root, BTNode<T> child)
{
if(!root)
{
return Null;
}
if(Root.left* == child || Root.right* == child)
{
return Root;
}
else
{
//recursively checks left tree to see if child node is pointed to
findParent(Root.left, child);
//recursively checks right tree to see if child node is pointed to
findParent(Root.right, child);
}
int findHeight(BTNode<T> thisNode)
{
if (Count.findParent(.root, thisNode) == null)
{
return 0;
}
return findHeight(thisNode.findParent) + 1;
}
My problem is that in the findHeight method, it calls the findParent() method, and I have to reference the root of the binary tree that the parameter thisNode comes from, and because this is just part of the class, I don't know how I am supposed to reference the root. The BT (binary tree) class has a function that returns the root of the tree, but since I have no Binary Tree to reference, I don't know what to do. Please Help!!!

Normally, the findHeight function wouldn't "worry" about finding the root of the tree -- it just finds the height of the tree below whatever node it's passed. It usually looks something like this:
int findHeight(BTNode <T> *thiNode) {
if (thisNode == NULL)
return 0;
int left_height = findHeight(thisNode->left);
int right_height = findHeight(thisNode->right);
return 1 + max(left_height, right_height);
}
It's then up to the user to pass in the root of the tree whose height they want.

Related

Binary Tree level order insertion c++

I want to insert in the tree but not using any other data structures like queue. I want to insert in level order and no matter what I code, it doesn't. Also I couldn't find any code without queues or things like that.
Here is my attempt;
void insert(int x) {
if (root == NULL) {
root = new node(x, NULL, NULL);
return;
}
node *temp = root;
node *prev = root;
while (temp != NULL) {
if (temp->left != NULL) {
prev = temp;
temp = temp->left;
} else if (temp->right != NULL) {
prev = temp;
temp = temp->right;
}
}
if (temp->left == NULL)
prev->left = new node(x, NULL, NULL);
else if (temp->right == NULL)
prev->right = new node(x, NULL, NULL);
}
I don't have a link for recursive insertion but it should work like this:
bool recursion(node * current_node, node * to_insert, int &max_depth, int cur_depth) {
if(max_depth < cur_depth) {
max_depth = cur_depth;
}
for (auto & current_child : {current_node->left, current_node->right})
if(current_child == NULL) {
if( max_depth > cur_depth ) {
current_child -> left = to_insert;
return true;
}
} else {
if(recursion(current_child, to_insert, max_depth, cur_depth + 1)) {
return true;
}
}
return false;
}
This does depth-first-search (not breadth-first, I was mistaken above, they are very similar in trees) from left to right. So we will first find the left-most leaf, then the one right next to it and so on. We will always track how deep we are in the tree. If at one point we find a node on the second deepest layer that hasn't got a child, it will add the node we want to insert at this point and recurse up the tree. Due to the order in which we traverse the tree, this will find the left most open spot, so exactly what you want.
This method can return false if the submost layer of the tree is full. Then we have to go down to the left-most leaf and insert the node at its left child. One can also save this leaf somehow when we first find it, but that seemed more complicate to me then just searching it again (this can be done without problem in a for-loop).
You can replace the recursive method by an iteration with a stack (there are many sources on the internet explaining how to make a recursive depth-first-search to a iterative one).
I don't really like the in-out-parameter max_depth but it was the easiest to do this.

Double-Threaded Binary Search Tree - Saving Parent & Grandparent Nodes in Order to Set Threads

For an assignment for school, I need to take a binary search tree and convert it into a double-threaded binary search tree. I have a general understanding on how the threads work, but I realize that in order to know where it exactly the threads are, I need to know the parent of the last inserted node (prev), as well as the parent of that node as well (twoBack). However, in my attempts to modify one of the functions in order to save those values, I can not quite get what I am looking for.
If someone could point out exactly what I'm doing wrong, and explain it to me so that I can learn from my mistakes, I'd greatly appreciate it. Thanks!
Both of these functions a are part of the class for the BST itself:
void insert(const Key& k, const E& e)
{
root = inserthelp(root, k, e);
nodecount++;
}
BSTNode<Key, E>* BST<Key, E>::inserthelp(BSTNode<Key, E>* root, const Key& k, const E& it)
{
if (root == NULL) // Empty tree: create node
{
return new BSTNode<Key, E>(k, it, NULL, NULL);
}
if (k < root->key())
{
if (prev != NULL)
twoBack = prev;
prev = root;
root->setLeft(inserthelp(root->left(), k, it));
}
else
{
if (prev != NULL)
twoBack = prev;
prev = root;
root->setRight(inserthelp(root->right(), k, it));
}
return root; // Return tree with node inserted
}
This question ha sbeen aswered due to the comments left.

Don't understand why I need a return on the last lines

I'm solving a problem about figuring out the minimum path to a leaf in a tree. I'm using BFS in C++ with a queue that stores a node and the current depth.
I traverse the tree in BFS adding nodes to my queue as I go along. As soon as I reach my first leaf I exit my cycle.
I don't understand why I need to add the return 0; line at the end of the program (commented on the code).
If I remove that line I get an error saying that the function got to the end without a return.
In which case will I need it?
class TreeDepth{
TreeNode* node;
int depth;
public:
TreeDepth(int depth, TreeNode* node): depth(depth), node(node) {}
TreeNode* getNode() {return node;}
int getDepth() {return depth;}
};
class Solution {
public:
int minDepth(TreeNode* root) {
if(!root)
return 0;
else
{
std::queue<TreeDepth> depthQ;
TreeDepth nodeDepth(1,root);
depthQ.push(nodeDepth);
while(!depthQ.empty())
{
TreeDepth currentNode = depthQ.front();
depthQ.pop();
if(!currentNode.getNode()->left && !currentNode.getNode()->right)
return currentNode.getDepth();
else
{
if(currentNode.getNode()->left)
{
TreeDepth leftNodeDepth(currentNode.getDepth() + 1, currentNode.getNode()->left);
depthQ.push(leftNodeDepth);
}
if(currentNode.getNode()->right)
{
TreeDepth rightNodeDepth(currentNode.getDepth() + 1, currentNode.getNode()->right);
depthQ.push(rightNodeDepth);
}
}
}
}
return 0; // why do I need this line?
}
};
Because you have paths in the function that exit but don't return a value. For instance, if depthQ IS empty, your code would exit without returning anything (but for that final 'return 0'). And you've declared your function to return an int. So all code paths must return some int.

C++ Binary Search Tree Insertion functions

Helly everyone,
I took a C++ coding course with practically no prior knowledge(my understanding of pointers is still somewhat shakey)at University this semester.
I have to implement a binary search tree in C++ and my problem is as follows:
Over a predefined Node structure with values and pointers to a left and a right node I am supposed to implement several functions, two of them being:
void InsertNode(Node* root, Node* node)
which is supposed to fit the handed node into the given tree "root",
and another one called
void InsertValue(Node* root, int value)
which should create a new instance of the node struct with the passed value and fit it in the given tree "root". To do so I am supposed to use both CreateNode (simple function to create Node* pointer of a new Node instance with int value and left/right pointers set to NULL) and InsertNode.
Im kind of running in a treadmill here and i dont think i really understand how the functions are supposed to work(eg. the difference between them).
Yesterday i wrote this function:
void InsertNode(Node* root, Node* node){
if(root == NULL){
root = CreateNode(node->value);
}
else if(root->value < node->value){
if(node->left != NULL){
InsertNode(root, node->left);
}
else{
node->left = CreateNode(root->value);
}
}
else if(root->value > node->value){
if(node->right != NULL){
InsertNode(root, node->right);
}
else{
node->right = CreateNode(root->value);
}
}
}
Since im not really able to test these functions without the later functions that will actually build the tree with given nodes i was curious if i could get some help here with the next functions InsertValue(what is it supposed to do that InsertNode doesnt do already? :S)
Greetings and thanks in advance.
Initial note: This answer assumes that the InsertNode function is initially called with root being the root of the tree, and node being the node to insert into the tree.
One problem is this statement:
root = CreateNode(node->value);
Since the argument root is passed by value, which means that it is copied, the assignment will only change the local copy. Once the function returns the original pointer that you pass to the function will not have changed.
You need to pass the pointer by reference, meaning the root argument references the original variable passed in to the function, instead of it being copied. You do this by using an ampersand when declaring the argument:
Node*& root
The above means that root is a reference to a pointer to Node.
So the complete InsertNode declaration should look like
void InsertNode(Node*& root, Node* node)
There are also other problems, for example these lines are not correct:
if(node->left != NULL){
InsertNode(root, node->left);
}
else{
node->left = CreateNode(root->value);
}
This is not correct because node->left should be NULL always, which makes you create a new node using the value from the root of the tree, and assign it to node->left, but you never insert node in the tree.
What you should instead do is simply
InsertNode(node->left, node);
Of course you should do the same change for setting the right branch.
Combining the two solutions above, your function would look like
void InsertNode(Node*& root, Node* node)
{
if (root == 0)
root = node;
else if (root->value < node->value)
InsertNode(root->left, node);
else
InsertNode(root->right, node);
}
This function also solves a third problem with your current code: What if node->value is equal to root->value? The above function puts it in the right branch.
When you are creating a tree, value are also assigned with each node. See following code:
typedef struct BST {
int data;
struct BST *lchild, *rchild;
} node;
void insert(node *root, node *new_node) {
if (new_node->data < root->data) {
if (root->lchild == NULL)
root->lchild = new_node;
else
insert(root->lchild, new_node);
}
if (new_node->data > root->data) {
if (root->rchild == NULL)
root->rchild = new_node;
else
insert(root->rchild, new_node);
}
}
node *new_node, *root;
int main()
{
new_node = get_node();
printf("\nEnter The Element ");
scanf("%d", &new_node->data);
if (root == NULL) /* Tree is not Created */
root = new_node;
else
insert(root, new_node)
}
The below code is in Python and is used for insertion in a BST ::
class Node :
def __init__(self.key):
self.left = None
self.right = None
self.val = key
def insert(root.node):
if root is None :
root = node
else :
if root.val < node.val:
if root.right is None :
root.right = node
else :
insert(root.right, node)
else :
if root.left is None :
root.left = node
else :
insert(root.left, node)
def inorder(root):
if root :
inorder(root.left)
print(root.val)
inorder(root.right)
# Driver program to test the above functions
# Let us create the following BST
# 50
# / \
# 30 70
# / \ / \
# 20 40 60 80
r = Node(50)
insert(r,Node(30))
insert(r,Node(20))
insert(r,Node(40))
insert(r,Node(70))
insert(r,Node(60))
insert(r,Node(80))
# Print inoder traversal of the BST
inorder(r)

Making a delete function for a binary search tree in C++

Edited*: I'm working on the delete function for a binary search tree. I'm just working on the first case right now. I think this is correct, but I'm wondering if it can be done recursively, or more efficiently. Any help is appreciated. Assume BSTSearch searches for a node, isLeaf returns true if the node is a leaf, and each node has a pointer that allows them access to their parent.
void
BinarySearchTree::BSTDelete(int x, BSTNode *node){
BSTNode *deleteNode;
deleteNode = BSTSearch(x,node);
if(isLeaf(deleteNode)){
if(deleteNode->sortkey > (deleteNode->parent)->sortkey){
delete (deleteNode->parent)->right;
(deleteNode->parent)->right = NULL;
}
else{
delete (deleteNode->parent)->left;
(deleteNode->parent)->left = NULL;
}
}
You don't need a pointer to the parent. Here is a recursive version that should work: (pass by reference (&), in case you don't know, allows you to modify the variable, similar to pass by pointer; BSTNode *& is a pointer passed by reference, so we can modify the value of node->left/right (pointers) (not just what they're pointing to))
void BinarySearchTree::BSTDelete(int x, BSTNode *&node)
{
if (node == NULL)
return;
if (x == node->sortKey)
{
if (isLeaf(node))
{
delete node;
node = NULL;
}
else
{
// other stuff goes here
}
return;
}
else if (x < node->sortKey)
BSTDelete(x, node->left);
else
BSTDelete(x, node->right);
}