Binary Search Tree Insertion using a void function - algorithm

I have written two different codes for inserting into a binary tree, one works whereas other doesn't.
This is how my node looks:
struct node
{
int data;
node *left;
node *right;
};
The following is the code for node* newnode(int a)
node* newnode(int a)
{
node *temp=new node;
temp->data=a;
temp->left=nullptr;
temp->right=nullptr;
return temp;
}
And following are the two different codes for insertion:
This one returns a pointer to the node:
node* insertion(node *root, int a)
{
if(root==nullptr)
return newnode(a);
else if(a<root->data)
root->left=insertion(root->left, a);
else
root->right=insertion(root->right, a);
}
This one returns void:
void insertion2(node *root,int a)
{
if(root==nullptr)
root=newnode(a);
else if(a<root->data)
insertion2(root->left,a);
else
insertion2(root->right,a);
}
The one which returns void doesn't work. And as per the analysis I made, after the function call, root is still nullptr. Can anyone explain me why does it not work?

Notice that in the insertionversion you have root->left = insertion(root->left, a) and root->right = insertion(root->right, a), but you have nothing to the same effect in insertion2. In effect, insertion2 does nothing except leak memory.

To answer your question.
The problem with your insertion2 function is that the root variable will point to nullptr(NULL) at the called place and a new memory is allocated and pointed to a local reference inside insertion2() function. The reference change to a new memory location will not have any impact on the reference # calling place. As pointed by others, this call will always leak memory in #clearer answer.
To make this function to work. Move the object creation part # calling place and leave just the insert to this function.
something like the below should work.
void insertion2(node *root, node *new_node)
{
if(root==nullptr)
root=new_node;
else if(a<root->data)
insertion2(root->left,new_node);
else
insertion2(root->right,new_node);
}
// Create the new node and call the insert function
new_node = newnode(a);
insertion2(root, new_node);
Hope it clarifies your doubt!

in 2nd function root is always a local variable so updating it doesn't change main root variable, since the pointer itself is not passed by reference. You can achieve this by using call by reference, just change your
function heading as follows: void insertion2(node *&root,int a).

This way is working fine while using void return type. Declare a global variable, first.. it is set to one if the node to be inserted is first.. later change it to 0.
void insertRoot(struct node* newnode){
root=newnode;
}
void insert(struct node* root, int data)
{
if(first==1){
insertRoot(createNode(data));
first=0;
}else{
if (data < root->data){
if(root->left==NULL){
root->left=createNode(data);
}else{
insert(root->left,data);
}
}
else if (data > root->data){
if(root->right==NULL){
root->right=createNode(data);
}else{
insert(root->right,data);
}
}
}
}

The Root pointer from the calling method needs to be updated as well. So, you'll have to call the Insert2 method using something similar: Insert2(&BSTNodePtr, a). When you pass the address of the variable BSTNodePtr, the Insert2 method can update it's content.
Try this instead:
void Insert2(BSTNode **root, int a){
if (*root==NULL){
*root = new BSTNode(a);
}
else if (a<= (*root)->data){
Insert2(&((*root)->left), a);
}
else{
Insert2(&((*root)->right), a);
}
}

Related

Calling parent struct inherited methods

I have a struct A that inherits from other classes (which I'm not allowed to change). Inside A and it's methods I can call inherited methods (lets say A_method(int i), for example) without problem but when I tried to write a nested struct (lets say In) and call A_method(int i) and there is were I'm stuck.
The initial code looks like this, and I can't change it, is some kind of college assigment.
#include "Player.hh"
struct A : public Player {
static Player* factory () {
return new A;
}
virtual void play () {
}
};
RegisterPlayer(PLAYER_NAME);
Then I tried this:
#include "Player.hh"
struct A : public Player {
static Player* factory () {
return new A;
}
//My code
struct In {
int x;
void do_smthing() {
A_method(x);
}
}
virtual void play () {
}
};
RegisterPlayer(PLAYER_NAME);
Ok, from a beginning I knew I could't do this, for In to see it's parent class it should have a pointer to it but In is a often instantiated object in my code and I wanted to avoid passing this constantly to a constructor so I tried this aproach:
#include "Player.hh"
struct A : public Player {
static Player* factory () {
return new A;
}
//My code
static struct Aux
A* ptr;
Aux(A* _p) { ptr = _p; }
} aux;
struct In {
int x;
void do_smthing() {
aux.ptr->A_method(x);
}
}
virtual void play () {
//the idea is to call do_smthing() here.
}
};
RegisterPlayer(PLAYER_NAME);
What I want to avoid (if possible) is something like this:
struct In {
int x;
A* ptr;
In (A* _p) : ptr(_p) {}
void do_smthing() {
ptr->A_method(x);
}
}
The main reason for this: I have more struct definitions and they they are instantiated multiple times through the rest of the (omitted) code, and I don't like the idea of seeing In(this) so many times.
I don't know if I'm completly missing something or what I want to do it's just not possible... Please ask for clarifications if necessary.
(Also, performance is kind of critical, my code will be tested with limited CPU time so I kinda have to avoid expensive approachs if possible. Using C++11)
There is no way you can skip passing the this pointer. Instead, you could create a helper function in A:
template <typename InnerType, typename ...Params>
InnerType makeInner(Params&&... params)
{
return InnerType(this, std::forward<Params>(params)...);
}
Then you can use
auto * a = A::factory();
auto inner = a->makeInner<A::In>();
I have some suggestions which are not directly related to you question but may help:
A::facotry() returns a std::unique_ptr<A> instead of raw pointer
Try to describe what problem you are trying to solve. I have a strong feeling that there can be a better design other than creating many nested structs.
I don't see passing a this pointer could have any impact on the performance. The more important thing is to identify the path that is latency-sensitive and move expensive operations out of those paths.

What caused the memory leak in this code?

I am inspecting the code that may cause memory leak. I know something is wrong with std::set.erase(this) and the destructor of SomeObject. So how to fix it?
class SomeObject;
////....
std::set<SomeObject*> managedObjects;
///.....
class SomeObject{
public:
SomeObject(){ managedObjects.insert(this); }
SomeObject(SomeObject&& S)/*move cter*/{ managedObjects.insert(this); }
virtual ~SomeObject() { managedObjects.erase(this); }
////....
};
////....
void clearAllObjects() {
for(auto p : managedObjects){
if(p){
delete p;
}
}
managedObjects.clear();
}
////....
When you delete inside clearAllObjects() it will result in managedObjects.erase(this) which is the same as managedObjects.erase(p).
This means that the internal iterator in the range based for-loop may be invalidated (I'm not sure). If it is, it'll try to do ++internal_iterator; on an invalid iterator - with undefined behavior as a result.
To be safe, you could copy the iterator and step that to the next in the set before doing erase.
Also note: There's no need to check if what you delete is a nullptr or not. It's mandated by the standard to have no effect if that's the case.
Example:
void clearAllObjects() {
for(auto pit = managedObjects.begin(); pit != managedObjects.end();) {
delete *pit++ // postfix ++ returns a copy of the old iterator
}
managedObjects.clear();
}
A side effect by having this managedObjects set is that you can't have automatic variables of SomeObject.
int main() {
SomeObject foo;
clearAllObjects(); // deletes the automatic object "foo" (not allowed)
} // <- the automatic object is destroyed here

Class method callbacks in D to C functions

I'm writing a simple, lightweight engine in D. For the input calls I use GLFW3. The library in question uses callbacks to send input events to the program.
What I would like is to use a method from a class as the callback function, rather than a function. This is proving difficult (just as it is in C++). I believe there is an elegant way to do it, but this is how I got it right now.
public void initialise(string logPath) {
[...]
m_Window = new RenderWindow();
m_Window.create();
// Lets set up the input loop.
GLFWkeyfun keyCB = function(GLFWwindow* win, int key, int scancode, int action, int mods) {
printf("Got key event: %d:%d:%d:%d\n");
RenderWindow rw = Root().getRenderWindow();
switch (key) {
case KeyboardKeyID.Q:
glfwSetWindowShouldClose(win, true);
break;
case KeyboardKeyID.H:
if (rw.hidden) {
rw.show();
} else {
rw.hide();
}
break;
default:
break;
}
};
glfwSetKeyCallback(m_Window.window, keyCB);
}
Here is the definition of the callback setting function and type:
extern (C) {
alias GLFWkeyfun = void function(GLFWwindow*, int, int, int, int);
GLFWkeyfun glfwSetKeyCallback(GLFWwindow*, GLFWkeyfun);
}
What I would like to do instead, is create a method that is part of the class. Is there any way to do this?
A solution I tried was a static method wrapped around in extern (C), this worked for calling it, but then I could (obviously) not access this or any other methods, which defeats the point of the exercise.
Thanks in advance.
The way I'd do it is to have a static map of the pointers to the class, so like:
static YourWindowClass[GLFWwindow*] mappings;
Then, in the constructor, once you get a GLFWwindow pointer, add it right in:
mappings[m_Window.window] = this;
Now, make the static extern(C) function to use as the callback. When it gets a pointer from C, look up your class reference in that mappings array and then go ahead and call the member function through that, forwarding the arguments.
So a bit of an extra step, but since it doesn't look like the callback lets you pass user-defined data to it (BTW, attention all lib writers: user-defined void* to the callbacks is sooooo useful, you should do it whenever possible!), but since it doesn't do that the associative array is the next best thing.
Well, I have figured it out my own. The solution I went with was a Singleton class InputManager. Instances of RenderWindow attach themselves to it with the following function. The InputManager then creates an anonymous function() for the RenderWindow that receives events, which then calls a function that handles the actual event.
The idea is then that listeners attach themselves to the InputManager and receive keyboard events for the RenderWindow they requested.
class InputManager {
private static InputManager m_Instance;
private RenderWindow[] m_Watched;
private KeyboardListener[][RenderWindow] m_KeyListeners;
public void recvKeyEvent(GLFWwindow* w, int k, int c, int a, int m) {
writeln("Received key: ", k);
}
public void watch(RenderWindow win) {
if (!isWatched(win)) {
// Relay the key callbacks onto the InputManager.
GLFWkeyfun keyCB = function(GLFWwindow* w, int k, int c, int a, int m) {
InputManager().recvKeyEvent(w, k, c, a, m);
};
glfwSetKeyCallback(win.window, keyCB);
}
}
private bool isWatched(RenderWindow win) {
foreach(RenderWindow w; m_Watched) {
if (win == w) {
return true;
}
}
return false;
}
public static InputManager opCall() {
if (m_Instance is null) {
m_Instance = new InputManager();
}
return m_Instance;
}
private this() {
// nothing
}
}
Works like a charm, now to figure out how to properly attach listeners elegantly.
For those curious, the full source code with how this is set up can be found at https://github.com/Adel92/Mage2D. I hope it helps someone else in a similar position with callbacks.

Binary search tree insertion method doesn't work

I want to implement a insertion method for a Binary search tree, and come up with a solution below. I know there are plenty of code examples but I wonder what is the problem in my implementation? Or is there a problem? When I had traced it I thought I have missed something.
public void insertBST(Node<Double> head, int value){
if (head == null){
head = new Node<Double>(value);
return;
}
else {
if (head.getValue() > value)
insertBST(head.getLeft(), value);
else
insertBST(head.getRight(), value);
}
}
When you reassign a passed parameter, you're only changing the local variable, not the value passed to the function. You can read this question for more information - Is Java "pass-by-reference"? This is Java, right? Either way, a similar argument likely applies.
This is the problem with this line of code:
head = new Node<Double>(value);
You aren't changing the value passed into the function, so you never add to the tree.
You have two alternatives here, either the option presented by amdorra, or returning the current node:
public void insertBST(Node<Double> current, int value)
{
if (current == null)
{
return new Node<Double>(value);
}
else
{
if (head.getValue() > value)
head.setLeft(insertBST(head.getLeft(),value));
else
head.setRight(insertBST(head.getRight(),value));
return current;
}
}
To call the function, you can simply say:
root = insertBST(root, value);
With alternatives, the root will have to be handled as a special case.
at the beginning of you function you are adding the new Node to a part you will never have access to outside this function
so i will assume that your Node class looks like the following
Class Node{
private Node left;
private Node right;
//constructor, setters and getters and stuff
}
you could modify your code to look like the following:
if (head.getValue() > value){
if(head.getLeft == null) {
head.setLeft(new Node<Double>(value));
return;
}
insertBST(head.getLeft(),value);
}
else{
if(head.getRight == null) {
head.setRight(new Node<Double>(value));
return;
}
insertBST(head.getRight(),value);
}
you should also remove this part if (head==null) and always make sure you are sending a valid Node to the first call

parent of a node in a binary tree by searching given key

this is the function in c that's not giving me the solution
struct node* serch(struct node *ptr,int x)
{
if(ptr->data==x)
{
printf(" root of tree itself ");
}
else
{
struct node *ptr1,*ptr2;
ptr1=ptr->left;
ptr2=ptr->right;
while((ptr1->data!=x)&&(ptr2->data!=x))
{
if(ptr->data>x)
{
ptr=ptr1;
ptr1=ptr->left;
ptr2=ptr->right;
}
else if(ptr->data<x)
{
ptr=ptr2;
ptr1=ptr->left;
ptr2=ptr->right;
}
}
return ptr;
}
}
THE code works fine for the node's having both the children(particularly works fine upto the level the tree is balanced) but after that it doesn't work and gives the error
parentnode.exe has stopped working ,windows is checking for a solution.
You have several bugs
you are not returning something for the case ptr->data==x. Your c compiler should have given a warning that not all paths return a value.
you are not checking for nulls

Resources