How to delete the root node in a 1-layer BST [closed] - c++

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
I have a simple BST node struct:
struct Node {
int value;
Node* left;
Node* right;
}
Back in C, the constructor would be like:
Node* construct_node(int value){
Node* node = (Node*) malloc(sizeof(Node));
node->data = value;
node->right = NULL;
node->left = NULL;
}
Making it is easy to delete the root, since it is just another dynamically allocated node.
In C++, however, the constructor doesn't return anything, and the root is the only node that is statically allocated.
Node::Node(const int& value, Node* left, Node* right) {
this->value = value;
this->left = left;
this->right = right;
}
Is there any way to go around this so that deleting the root is possible just like in C, even if the user declares it statically in the main? Or a way to strict the user to declare it only using 'new'? Keeping it 1-layer without adding another class as the tree holding nodes by pointing to the root one.

You can simply not define a constructor of this type at all. Just create a default constructor,
Node::Node(){}
And make all members private with getters. This will make this constructor useless.
Now create a function which behaves just like the one in C,
Node* Node::new_node(int val, Node *l, Node *r){
Node *n = new Node();
n->left = l;
n->right = r;
return n;
}
This will force people to use this constructor only.

Okay, I think you have some confusion about pointers between C and C++. They're the same thing. There's nothing at all that keeps you from writing this method in C++:
Node * construct_node(int value) {
Node * node = new Node(value, nullptr, nullptr);
return node;
}
At which point, all that really changes in deleting the node is that you use:
delete node;
Instead of:
free(node);
Everything else remains the same. Now, you have to decide what happens when you delete a Node. Do you want destructor that deletes the left and right nodes recursively? Or do you let them potentially get lost? So you're not done.

Related

Segmentation Fault with declared variables C++ [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
I am trying to create a node class. The node class has two variables: an int, and a pointer to another node. Here are my node constructors. I found on another stack overflow that in order to allocate memory for values, you need to include a "new ... " phrase.
Node::Node() {
next = new Node;
}
Node::Node(int new_num) {
num = new_num;
next = new Node;
}
I am using a method called AssignArray which takes an array of ints and turns that into a linked list of nodes. Parts of it work, except when I try to use the setNext method on my node. The setNext method is just a regular setter.
void Node::setNext(Node* new_next) {
next = new_next;
}
Node* Node::AssignArray(int list[], int i, int size) {
if (i == size) {
return NULL;
}
else {
Node new_node(list[i]);
i++;
new_node.setNext(new_node.AssignArray(list, i , size));
return &new_node;
}
}
Here is my main function so far:
int main() {
int nums1[] = {1,2,3,4,5};
int nums2[] = {1,3,5,7,9};
Node node1 = Node();
int nums1_size = sizeof(nums1)/sizeof(nums1[0]);
node1.AssignArray(nums1, 0, nums1_size);
The main issue is that you're calling setNext with the return value from AssignArray, which you return as &new_node, which is a pointer to a local Node that you allocated on the stack. As soon as the function returns, the stack unwinds and that Node instance ceases to exist, leaving the pointer dangling.
At the very least you should be doing:
Node* new_node = new Node(list[i]);
...
return new_node;
But I also feel like we're missing some things here. It would be nice to see the definition of Node. And how is this constructor not producing a stack overflow?
Node::Node() {
next = new Node;
}
In the constructor you do new Node which will call this same constructor again... which will call the constructor again...
Hmm.
I think new node added on constructor while infinite loop through itself.
Node::Node() {
next = new Node;
}
It will be better to avoid this type of calling.

circular doubly linked list insertion at the end [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
I was going through dsa doubly circular list, and was practicing insertion of elements to it, after entering the first element my program ends abruptly.....is there a mistake in my insertafterfunction.i get a segmentation fault error .just help me through I cant find what has gone wrong..
#include<iostream>
struct Node{
int data;
Node* next;
Node* prev;
};
Node* headnode;
void insert(int data){
Node* newnode = new Node;
newnode->data= data;
newnode->next=headnode;
newnode->prev=headnode;
headnode=newnode;
}
void insertafter(int data){
Node* newnode=new Node;
newnode->data=data;
newnode->next=headnode;
Node* existingnode = headnode;
while(existingnode->next!=headnode){
existingnode=existingnode->next;
}
existingnode->next=newnode;
newnode->prev= existingnode;
headnode->prev=newnode;
}
void printnode(){
Node* newnode=headnode;
while (newnode->next!=headnode){
std::cout<<newnode->data<<"->";
newnode=newnode->next;
}
std::cout<<"\n";
}
int main(){
headnode=NULL;
int x,data;
std::cin>>x;
for(int i=0;i<x;i++)
{
std::cin>>data;
if(i==0)
{
insert(data);
}
else
{
insertafter(data);
}
printnode();
}
}
For example this while loop within the function insertafter
while(existingnode->next!=headnode){
existingnode=existingnode->next;
}
invokes undefined behavior because after calling the function insert data members prev and next of the head node are equal to nullptr.
See the function insert
void insert(int data){
Node* newnode = new Node;
newnode->data= data;
newnode->next=headnode; // here headnode is equal to nullptr
newnode->prev=headnode; // And here headnode is equal to nullptr
headnode=newnode;
}
It seems you mean at least the following function definition
void insert(int data){
Node* newnode = new Node;
newnode->data= data;
headnode=newnode;
newnode->next=headnode;
newnode->prev=headnode;
}
That is after calling the function data members prev and next of the head node will point to the head node itself.
In general the separate function insert does not make a sense because it may be called (provided that it will be written correctly) only once.
Also the function printnode will output nothing if the list contains only the head node due to the condition in the while statement
Node* newnode=headnode;
while (newnode->next!=headnode){

Deep Copy of a linked list that returns a Node pointer

I keep getting a segmentation fault on my deep copy of a linked list. I use this deep copy in my Copy Contructor and my assignment operator (operator=) and have come to the conclusion that it is this that is seg faulting.
bigint::Node* bigint::deepcopy(bigint::Node* target){
bigint::Node* current = target;
bigint::Node*cpy = new Node;
cpy->digit = current->digit;
Node* const hd = cpy;
current = current->next;
while(current != nullptr){
bigint::Node* tmp = new Node;
tmp->digit = current->digit;
cpy->next = tmp;
cpy = cpy->next;
current = current->next;
}
return hd;
}
My Node struct looks like:
private:
struct Node{
int digit;
Node* next;
};
Node* head;
static Node* deepcopy(Node* target);
My class is closed and all, just showing what is in private that is related to this function. Thanks in advance for any advice.
When you use your deepcopy function, you must make sure that the paramater target is not nullptr. So, you should check if (target == nullptr) at the beginning of your deepcopy function.
Also, after the while loop finished, you should set the tail of your new list to nullptr.
From the information you post, it seems you have use ->digit or ->next on a null pointer.
If you still get this error, you'd better provide a example code.

Runtime error happens when deleting a node of the linklist [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
Here's my C++ code of a simple structured linklist.
#include <iostream>
using namespace std;
class Node{
public:
int data;
Node* next;
Node* prev;
Node(){
data=-1;
next=NULL;
prev=NULL;
}
Node(int d,Node *nnext){
data=d;
next=nnext;
}
void add(Node* nnext){
next=nnext;
nnext->prev=this;
}
};
void print(Node* head){
Node* cNode;
cNode=head;
while (cNode!=NULL){
cout <<"["<<cNode->data<<"]" << endl;
cNode=cNode->next;
}
}
void insertAfter(Node* pNode, Node* nNode){
nNode->next = pNode->next;
pNode->next = nNode;
pNode->next->prev = nNode;
}
void deleteNode(Node* b){
Node* c=b->next;
Node* a=b->prev;
a->next=c;
c->prev=a;
delete b;
}
void main(){
Node* head;
head=new Node();
head->data=1;
Node * currentNode=head;
for (int i=2;i<=5;i++){
Node* nNode=new Node(i,NULL);
currentNode->add(nNode);
currentNode=nNode;
}
cout << currentNode->data << endl;
print(head);
insertAfter(head, new Node(99,NULL));
//deleteNode(currentNode);
print(head);
}
The case checking is unnecessary because I just need the concept of the linklist. If you have another version of these kind of simple linklist code, please let me know! Thank you!
Your deleteNode() function does not check whether c and a are non-NULL, but immediately dereferences them. This means that your program will crash if you try to delete the first or last node of the list.
Your insertAfter() function also sets pointers in the wrong order, causing nNode->prev to point to itself.
Your deleteNode function is not taking care of the case when you delete the "head" element.
Let's take this list as an example:
head -> n1 -> n2 -> n3 (each of this nodes also has a link to the node before it, just as you did in your code)
If you call deleteNode(head), the following will happen:
Node* c=b->next; // b = head, c = head.next = n1
Node* a=b->prev; // b = head, a = head.prev = NULL
a->next=c; // a = NULL, then NULL->next
You can't access to a variable of a NULL object, that's why you are receiving that runtime error.
P.S: If you want to improve you understanding of data structures I recomend you this book: https://mitpress.mit.edu/books/introduction-algorithms

Am I add the item in front of linked-list correctly [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Closed 9 years ago.
Improve this question
In this case, I need to implement addFront() method which is to keep adding a integer in front of a linked-list.
class Node{
public:
int data;
Node* next;
Node* prev;
}
class List {
void addFront(int item);
protected:
Node* dummyNode;
int numItems; //number of item is the linkedlist
};
Below is what I tend to implement addFront():
void addFront(int data){
Node* head = new Node();
if(numItems == 0) //if no item in the list.
{
//Set the head node to be dummyNode
head = dummyNode;
//Because the next node the head is pointing to is NULL.
head -> next = NULL;
}
//Create a new node.
Node* newNode = new Node();
//Set value
newNode->data = data;
//Let the previous pointer of dummyNode points to newNode.
head->prev = newNode;
//Re-set head to be newNode.
head = newNode;
numItems++;
}
Am I doing correctly? If not, why? If yes, is there any better way to do this?
I won't go into too many details as this appears to be a homework assignment, but the short answer is, no.
Node* head = new Node();
if(numItems == 0) //if no item in the list.
{
//Set the head node to be dummyNode
head = dummyNode;
//...
}
You have a memory leak in the code above.
First of all name dummyNode which denotes the beginning of the list looks strange. It would be much better to substitute it for head. Also you need a variable that will point to the tail of the list.
As for your function then it is simple
void addFront( int data )
{
Node *head = new Node();
head->data = data;
head->next = dummyNode;
dummyNode->prev = head;
dummyNode = head;
numItems++;
}
Also it would be not bad if class Node had a constructor with parameters that to accept data and pointers. Class list also has to have an explicitly defined default constructor or its data members have to be initialized when they are defined.