Some binary tree based operations - c++

Hi I am trying to print the non-leaf(Internal) nodes in a binary search tree . But I am not getting the desired output . Kindly rectify my error or suggest me some better algorithm .
Here is my code .
void noleaf(struct node *here)
{
if((temp -> left != NULL) || (temp -> right != NULL))
{
printf("%d" , temp -> data) ;
if(temp -> left != NULL)
{
noleaf(temp -> left) ;
}
}
noleaf(temp -> right) ;
return 0 ;
}
Another function asks me to print the mirror image of the tree . Here I used .
struct node *Mirror(struct node *t)
{
if(t == NULL)
{
return 0 ;
}
else
{
nn = (struct node *)malloc(sizeof(struct node)) ;
nn -> data = t -> data ;
nn -> left = Mirror(t -> right);
nn -> right = Mirror(t -> left) ;
return nn ;
}
}
I am new to binary trees . Kindly help .

Your logic looks like this:
If the node has at least one child, print its data, and then
if the node has a left child, recurse into that
Then, recurse into the right child, regardless of whether it exists.
I think you'll agree that printing only nodes that have at least one child, and treating one child differently than the other, is unfair.
Recursion on binary trees usually take one of the following forms:
If it is a leaf, do your leaf processing (common for all cases)
Otherwise, either
do your internal node processing and then recurse into the subtrees (preorder), or
recurse into the subtrees and then do your internal node processing (postorder), or
recurse into the left subtree, then do your internal node processing, then recurse into the right subtree (inorder).
So a preorder traversal version of noleaf might be
void noleaf(struct node *here)
{
if (here == NULL)
{
// Do nothing
}
else
{
printf("%d", here->data);
noleaf(here->left);
noleaf(here->right);
}
}
or, simplified
void noleaf(struct node *here)
{
if (here)
{
printf("%d", here->data);
noleaf(here->left);
noleaf(here->right);
}
}

Is it really necessary to distinguish non-leaf nodes when printing the tree? I have re-sequenced your instructions (and omitted a return value - your compiler should have warned you about that).
void printree(struct node *here)
{
if (here != NULL)
{
printree (here->left);
printf("%d\n", here -> data) ;
printree (here->right);
}
}

For the noleaf function you have to check if here is not NULL (if it's NULL here->left or here->right will cause a segmentation fault or an error), then you have to check if here have sons, if it does have at least one then we aren't in a leaf, if we are then we print the content of the node.
void noleaf(struct node * here) {
if (here)
if (here->left || tree->right) {
printf("%d\n",here->data);
noleaf(here->left);
noleaf(here->right);
}
}
Note: One thing that I didn't understand was why you were using temp and not here.

Related

How to compare 2 linked lists in c++ and put matching data into another linked list

I want to compare two linked lists that contain book titles and then create a new linked list that only has the matching titles from the original lists. Currently I have already created both linked lists and can output both in alphabetical order. The problem comes when I try to compare and create the updated list with the matching titles.
I have tried to create a recursive function that takes in both lists as parameters and will call itself and move the second list to the next node if the titles don't match.
If they both match, then it again calls itself, but moves both lists up a node.
I'm still pretty new on using linked lists and recursion, but I feel like I'm on the right track. All of my other functions are working, I'm just not sure how to make this work and also how to call it in my main function.
Node *compare(Node *h, Node *j) {
Node* h_curr = h;
Node* j_curr = j;
Node* new_node;
Node* updated_list = NULL;
while ((h_curr->next != NULL) || (j_curr->next != NULL)) {
if (h_curr->data != j_curr->data) { // if not equal, then move j_head to the next link
compare(h_curr, j_curr->next);
//j_curr = j_curr->next;
}
else {
updated_list->data = h_curr->data;
new_node = newNode(updated_list->data);
return updated_list;
updated_list = updated_list->next;
compare(h->next, j->next);
}
}
return NULL;
}
#include<string>
#include<iostream>
//assumed node structure
struct Node{
Node(std::string str, Node* ptr = nullptr):data(str), next(ptr){}
std::string data{};
Node* next{};
};
//The following is your rucresive function
void compare(Node* & first, Node* & second, Node* & match) {
if(!first || !second ) return;//base case
if ( first -> data < second -> data) compare(first -> next, second, match );
else if ( first -> data > second -> data) compare(first , second -> next, match);
else{//match found
match = new Node{ first -> data};
compare(first , second -> next, match -> next);
}
}
//To disply the result (recursive function)
void display(Node* & root){
if(!root) return;
std::cout<<root->data<<" ";
display( root-> next);
}
//To test
int main(){
Node* first = new Node{"aaa"};
first->next=new Node{"ccc"};
first->next->next=new Node{"ccc1"};
first->next->next->next=new Node{"ccc3"};
first->next->next->next->next=new Node{"ccc4"};
first->next->next->next->next->next=new Node{"ddd"};
Node* second = new Node{"baaa"};
second->next=new Node{"ccc"};
second->next->next=new Node{"ccc1"};
second->next->next->next=new Node{"ccc2"};
second->next->next->next->next=new Node{"ccc4"};
Node* res;
compare(first, second, res);
display(res);
}

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.

How to reverse a singly linked list in C++?

I am trying to reverse a single linked list with this code but its not working properly.The following code not works in that case when the size of list is two otherwise it works well.I cannot find error in this code and spent a lot of time on it.Please tell me whats wrong with this code?
void list::reverse()
{
node *current = head;
if (current->next != NULL)
{
node *move = current->next;
while (move->next != NULL)
{
node *temp = move->next;
move->next = current;
if (current == head)
{
current->next = NULL;
}
current = move;
move = temp;
}
if (move->next == NULL)
{
move->next = current;
if (current == head)
{
current->next == NULL;
}
head = move;
}
}
}
You have:
A (== head) -> B -> C -> D
You want (?):
D (== head) -> C -> B -> A
I got lost in your algorithm completely, can't figure out how it would work, or how to fix it easily. Actually I have hard time to believe it works for longer lists. But too lazy to try.
Maybe try to understand this one (in pseudo C++), looks simpler to me?:
src = head;
reversed = nullptr;
while (nullptr != src) {
// node to insert at the beginning of reversed list
to_prepend = src;
// iterate trough all nodes in normal direction
src = src->next;
// now insert the currently read node at the head of reversed list
to_prepend->next = reversed;
reversed = to_prepend;
}
head = reversed;
I didn't wrote code+debug, so can't guarantee correctness, but it should work like this:
A (== head) -> B -> C -> D
current: A, reversed null, current updated to B (A->B), A->reversed(nullptr), reversed=A
current: B, reversed A, current to C (B->C), B->reversed(A), reversed=B
current: C, reversed B->A, current to D, C->reversed(B), reversed=C
current: D, reversed C->B->A, current to nullptr, D->reversed(C), reversed=D
current: nullptr: exit while
head = reversed (= D->C->B->A->nullptr).
Also in your code the:
current->next == NULL; is boolean expression, throwing the result away, not doing anything.

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)

Binary Tree findHeight

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.