Delete node from Linked List C++ - c++

I am working on iterative delete function that deletes node from a linked list, I think that the code is supposed to work fine. But when I can't use "delete" to delete the first Node of the List.
The code is:
#include
using namespace std;
struct Node
{
int data;
Node* next;
};
Node* GetNewNode(int data)
{
Node* newNode = new Node;
newNode->data = data;
newNode->next = NULL;
return newNode;
}
Node* Insert(Node *root, int data)
{
if (root == NULL)
{
root = GetNewNode(data);
}
else
root->next = Insert(root->next, data);
return root;
}
void Delete_k(Node *root, int k)
{
int i = 0;
Node* P = new Node;
if (k == 1)
{
P = root;
root = root->next;
delete P;
}
else
{
for (int i = 1; i <= k - 2; i++)
{
root = root->next;
}
root->next = root->next->next;
}
}
void Output(Node* root)
{
if (root == NULL)
{
root = root->next;
}
while (root != NULL)
{
cout << root->data << " ";
root = root->next;
}
}
int main()
{
int n, a, pos;
Node* root = NULL;
cout << "Input your list hear: ";
cin >> n;
while (n > 0)
{
root = Insert(root, n);
cin >> n;
}
Output(root);
cout << "\nDelete Pos?: ";
cin >> pos;
Delete_k(root, pos);
Output(root);
}
I have problem in this
void Delete_k(Node *root, int k)
{
int i = 0;
Node* P = new Node;
if (k == 1)
{
P = root;
root = root->next;
delete P;
}
else
{
for (int i = 1; i <= k - 2; i++)
{
root = root->next;
}
root->next = root->next->next;
}
}

The problem:
void Delete_k(Node *root, int k)
The value at root is pass by reference, but the pointer to it is not.
Result: Delete_k's root is a copy of main's root. Delete_K's root gets repointed and deleted. Main's root now points at garbage memory. End game program.
Solution:
Provide a reference to the root pointer so that it doesn't get copied.
void Delete_k(Node *& root, int k)
Or return root from Delete_k.
Node * Delete_k(Node * root, int k)
{
//existing code
return root;
}

Related

Trying to initialize a linked list using array

I need to define a class of linked list,List, in a way such that object of class can be defined in two ways,
List obj1 = L1();//head=0
List obj2 = L2(given_arr[], size of array) // I would be given an array, whose elements are elements of list
so, I need to form a construter for both,
for obj1, Its easy.
List(){head=0};
But I am not abe to do so for second type of object.
I tried to form a program for this.
#include <iostream>
using namespace std;
class List {
class node {
public:
int val;
node* next;
};
public:
node* head;
int arr[];
List() { head = 0; }
List(int arr[], int size);
void addnode(int value) {
node* newnode = new node();
newnode->val = value;
newnode->next = NULL;
if (head == NULL) {
head = newnode;
} else {
node* temp = head; // head is not NULL
while (temp->next != NULL) {
temp = temp->next; // go to end of list
}
temp->next = newnode; // linking to newnode
}
}
void display() {
if (head == NULL) {
cout << "List is empty!" << endl;
} else {
node* temp = head;
while (temp != NULL) {
cout << temp->val << " ";
temp = temp->next;
}
cout << endl;
}
}
};
List::List(int arr[], int size) {
int i;
head->val = arr[0];
for (i = 0; i < size; i++) addnode(arr[i]);
}
int main() {
int barr[4] = {9, 89, 0, 43};
List* M = new List();
List* L = new List(barr[4], 4);
L->display();
return 0;
}
This program doesn't work. Please suggest a way to do so.
Make these changes to your main().
int main() {
int barr[] = {9, 89, 0, 43}; // No need to specify size if you're initializing
// List* M = new List(); // unused
// Your array is barr, barr[4] makes no sense. You also don't allocate the List,
// the list allocates
List L = List(barr, sizeof(barr) / sizeof(barr[0]);
L.display(); // -> to .
return 0;
}
This now compiles, but immediately segfaults. Simply running the program in the debugger shows a simple error. The line head->val = arr[0]; attempts to dereference a null pointer. Which takes us to the next thing. Use nullptr, not NULL or 0.
Your array constructor was over-complicated, you just need this:
List::List(int arr[], int size) {
for (int i = 0; i < size; i++) addnode(arr[i]);
}
Your addnode() function already handled an empty list. Fixing that, your code should run. I made a couple other small changes, mostly trimming cruft out. Here's your complete code:
#include <iostream>
using namespace std;
class List {
class node {
public:
int val;
node* next;
};
public:
node* head = nullptr;
List() = default;
List(int arr[], int size);
void addnode(int value) {
node* newnode = new node();
newnode->val = value;
newnode->next = NULL;
if (head == NULL) {
head = newnode;
} else {
node* temp = head; // head is not NULL
while (temp->next != NULL) {
temp = temp->next; // go to end of list
}
temp->next = newnode; // linking to newnode
}
}
void display() {
if (head == NULL) {
cout << "List is empty!" << endl;
} else {
node* temp = head;
while (temp != NULL) {
cout << temp->val << " ";
temp = temp->next;
}
cout << endl;
}
}
};
List::List(int arr[], int size) {
for (int i = 0; i < size; i++) addnode(arr[i]);
}
int main() {
int barr[] = {9, 89, 0, 43};
List L = List(barr, sizeof(barr) / sizeof(barr[0]));
L.display();
return 0;
}

control insertion to BST according to user inputs

This is my code for binary search tree:
#include<iostream>
using namespace std;
struct node
{
int data;
struct node* left;
struct node* right;
};
node* createNode(int value)
{
node* newNode = new node;
newNode->data = value;
newNode->left = NULL;
newNode->right = NULL;
return newNode;
}
node* insert( node* root, int data)
{
if (root == NULL) return createNode(data);
if (data < root->data)
root->left = insert(root->left, data);
else if (data > root->data)
root->right = insert(root->right, data);
return root;
}
void inorder(node* root)
{
inorder(root->left);
cout<< root->data<<" ";
inorder(root->right);
}
int main()
{
node *root = NULL;
int n;
cout << "How many values do you want to enter" << endl;
cin >> n;
int no;
for (int i = 0; i < n; i++)
{
cin >> no;
insert(root, no);
}
inorder(root);
}
When I call display function/inorder in int main() it displays no values and the program stops with error
I am using loop to take input so it can take values upto to user specified value/range
but the display/inorder function is not working.
How can I resolve this issue?
In inOrder function you don't have stop condition!
and in the main should be root=insert(root, no);
#include<iostream>
using namespace std;
typedef struct node
{
int data;
struct node* left;
struct node* right;
}node;
node* createNode(int value)
{
node* newNode = new node;
newNode->data = value;
newNode->left = NULL;
newNode->right = NULL;
return newNode;
}
node* insert( node* root, int data)
{
if (root == NULL) return createNode(data);
if (data < root->data)
root->left = insert(root->left, data);
else if (data > root->data)
root->right = insert(root->right, data);
return root;
}
void inorder(node* root)
{
if(root == NULL)return;
inorder(root->left);
cout<< root->data<<" ";
inorder(root->right);
}
int main()
{
node *root = NULL;
int n;
cout << "How many values do you want to enter" << endl;
cin >> n;
int no;
for (int i = 0; i < n; i++)
{
cin >> no;
root=insert(root, no);
}
inorder(root);
}

I'm trying to code a binary search tree using c++ but the program takes only 2 inputs and stops

Notice the //, the program stops taking input and that is the main problem.
root->cand = data;
Here is the full code:
#include <bits/stdc++.h>
using namespace std;
struct node
{
int cand;
node *left;
node *right;
};
class candies
{
node *root;
public:
candies();
int add(int);
int check();
};
candies::candies()
{
root = NULL;
}
int candies::add(int data)
{
if (root == NULL)
{
root->cand = data; //code stops here
root->left = NULL;
root->right = NULL;
}
else
{
node *temp = root;
while (temp != NULL)
{
if (data < temp->cand)
{
temp = temp->left;
}
else
{
temp = temp->right;
}
}
temp = new node;
temp->cand = data;
temp->left = temp->right = NULL;
}
return 1;
}
int candies::check()
{
node *temp;
temp = root;
int data;
cin >> data;
while (temp != NULL)
{
if (temp->cand == data)
{
cout << "YES\n";
return 1;
}
else if (data < temp->cand)
temp = temp->left;
else if (data > temp->cand)
temp = temp->right;
}
cout << "NO\n";
return 0;
}
int main()
{
candies c;
int n;
cin >> n;
while (n--)
{
int data;
cin >> data;
c.add(data);
}
c.check();
}
The member function add is invalid and moreover has undefined behavior.
In this if statement
if (root == NULL)
{
root->cand = data; //code stops here
root->left = NULL;
root->right = NULL;
}
there is used a null-pointer to access memory.
In this else statement
else
{
node *temp = root;
while (temp != NULL)
{
if (data < temp->cand)
{
temp = temp->left;
}
else
{
temp = temp->right;
}
}
temp = new node;
temp->cand = data;
temp->left = temp->right = NULL;
}
the created node temp is not added to the tree. So the program has a memory leak.
The function can be written the following way. It is better to make its return type void. Otherwise the returned value 1 as in your function implementation does not make sense.
class candies
{
node *root;
public:
candies();
void add(int);
int check();
};
//...
void candies::add( int data )
{
node **current = &root;
while ( *current != nullptr )
{
if ( data < ( *current )->cand )
{
current = &( *current )->left;
}
else
{
current = &( *current )->right;
}
}
*current = new node { data, nullptr, nullptr };
}
You are first checking that root is NULL. If it is, you are changing its data. This is not good at all, and will cause a crash.
if (root == NULL)
{
root->cand = data; //code stops here
If root is NULL, you must create a root node first.
if ( root == nullptr ) {
root = new node;
root->cand = data;

A count function that counts the leaf nodes of a height balanced tree

I'm writing a function that counts the leaf nodes of a height balanced tree using struct and pointers. The function takes 3 arguments: the tree, pointer to an array and the maximum depth of the tree. The length of the array is the maximum depth. When function is called the array is initialized to zero. The function recursively follows the tree structure,
keeping track of the depth, and increments the right counter whenever it reaches a leaf. The function does not follow any pointer deeper than maxdepth. The function returns 0 if there was no leaf at depth greater than maxdepth, and 1 if there was some pointer togreater depth. What is wrong with my code. Thanks.
typedef int object;
typedef int key;
typedef struct tree_struct { key key;
struct tree_struct *left;
struct tree_struct *right;
int height;
} tree_n;
int count_d (tree_n *tr, int *count, int mdepth)
{
tree_n *tmp;
int i;
if (*(count + 0) == NULL){
for (i =0; i<mdepth; i++){
*(count + i) = 0;
}
}
while (medepth != 0)
{
if (tr == NULL) return;
else if ( tree-> left == NULL || tree->right == NULL){
return (0);
}
else {
tmp = tr;
*(count + 0) = 1;
int c = 1;
while(tmp->left != NULL && tmp->right != NULL){
if(tmp-> left){
*(count + c) = 2*c;
tmp = tmp->left;
return count_d(tmp, count , mdepth);
}
else if(tmp->right){
*(count + c + 1) = 2*c + 1;
tmp = tmp->right;
return count_d(tmp,count, mdepth);
}
c++;
mpth--;
}
}
}
What is wrong with my code
One thing I noticed is that you are missing return in the recursive calls.
return count_d(tmp, count , mdepth);
// ^^^ Missing
There are two such calls. Make sure to add return to both of them.
Disclaimer: Fixing this may not fix all your problems.
Correct Function To Insert,Count All Nodes and Count Leaf Nodes
#pragma once
typedef int itemtype;
#include<iostream>
typedef int itemtype;
#include<iostream>
#include<conio.h>
#include<string>
using namespace std;
class Node
{
public:
Node* left;
Node* right;
itemtype data;
};
class BT
{
private:
int count = 0;
Node* root;
void insert(itemtype d, Node* temp);//Override Function
public:
BT();//Constructor
bool isEmpty();
Node* newNode(itemtype d);
Node* getroot();
void insert(itemtype d);//Function to call in main
int countLeafNodes(Node * temp);
int countAllNodes();//to count all nodes
}
BT::BT()//constructor
{
root = NULL;
}
bool BT::isEmpty()
{
if (root == NULL)
return true;
else
return false;
}
Node* BT::newNode(itemtype d)
{
Node* n = new Node;
n->left = NULL;
n->data = d;
n->right = NULL;
return n;
}
void BT::insert(itemtype d)//Function to call in main
{
if (isEmpty())
{
Node* temp = newNode(d);
root = temp;
}
else
{
Node* temp = root;
insert(d, temp);
}
count++;//to count number of inserted nodes
}
void BT::insert(itemtype d, Node* temp)//Private Function which is overrided
{
if (d <= temp->data)
{
if (temp->left == NULL)
{
Node* n = newNode(d);
temp->left = n;
}
else
{
temp = temp->left;
insert(d, temp);
}
}
else
{
if (temp->right == NULL)
{
temp->right = newNode(d);
}
else
{
temp = temp->right;
insert(d, temp);
}
}
}
int BT::countAllNodes()
{ return count; }
int BT::countLeafNodes(Node* temp)
{
int leaf = 0;
if (temp == NULL)
return leaf;
if (temp->left == NULL && temp->right == NULL)
return ++leaf;
else
{
leaf = countLeafNodes(temp->left) + countLeafNodes(temp->right);
return leaf;
}
}
void main()
{
BT t;
t.insert(7);
t.insert(2);
t.insert(3);
t.insert(15);
t.insert(11);
t.insert(17);
t.insert(18);
cout<<"Total Number Of Nodes:" <<t.countAllNodes() <<endl;
cout << "Leaf Nodes:" << t.countLeafNodes(t.getroot()) << endl;
_getch();
}
Output:
Ouput

Linked List insertion/deletion

// ConsoleApplication1.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
using namespace std;
struct Node {
int data;
Node* next;
};
Node* head = NULL;
int size;
Node* tail = NULL;
void printLinkedList() {
Node *search = head;
if (head == NULL) {
cout << "linkedlist is empty" << endl;
}
else {
while (search != NULL){
cout << search->data << endl;
search = search->next;
}
}
}
int sizeLinkedList() {
size = 1;
Node* current = head;
while (current->next != NULL) {
current = current->next;
size = size + 1;
}
cout << size << endl;
return size;
}
Node *getNode(int position){
Node *current = head;
for (int i = 0; i<position; i++)
{
current = current->next;
}
return current;
}
void appendNode(int n) {
Node *newNode = new Node; //creating new node
newNode->data = n;
newNode->next = NULL;
if (head == NULL)
{
head = newNode;
return;
}
else {
Node *current = head;
while (current->next != NULL) {
current = current->next;
}
current->next = newNode;
}
}
void insertNode(int n, int position) {
Node *newNode = new Node;
newNode->data = n;
newNode->next = NULL;
int size = sizeLinkedList();
if (position = 0){
if (head == NULL) {
head = newNode;
}
else{
newNode->next = head;
head = newNode;
}
}
else if (position == size) {
appendNode(n);
}
else {
Node *prevNode = getNode(position-1);
Node *nextNode = getNode(position);
prevNode->next = newNode;
newNode->next = nextNode;
}
}
void deleteNode(int position) {
Node *currentNode;
int size = sizeLinkedList();
if (size == 0) {
return;
}
if (position == 0) {
currentNode = head->next;
head = currentNode;
}
else if (position == size-1) {
getNode(position - 1)->next = NULL;
delete getNode(position);
}
else {
getNode(position - 1)->next = getNode(position+1);
delete getNode(position);
}
}
//making a dynamic array only via pointers in VC++
void makeArray() {
int* m = NULL;
int n;
cout << "how many entries are there?"<<endl;
cin >> n;
m = new int[n];
int temp;
for (int x = 0; x < n; x++){
cout << "enter item:"<< x+1<< endl;
cin >> temp;
*(m + x) = temp;
}
for (int x = 0; x < n; x++){
cout << x+1 + ":" << "There is item: "<<*(m+x) << endl;
}
delete[]m;
}
int main() {
int x;
//makeArray();
appendNode(1);
appendNode(2);
appendNode(32);
appendNode(55);
appendNode(66);
//insertNode(2, 0);
printLinkedList();
deleteNode(3);
printLinkedList();
sizeLinkedList();
cin >> x;
}
Im just trying to code a Linked List with a couple of functions for practice
My Delete function, the last else statement isnt working, and logically I cant figure out why,
as for my insert function none of the statements are working, not even at head or position 0. However appending items, returning size, printing the list, deleting the first and last elements works.
thanks!
sizeLinkedList won't work correctly if the list is empty (it cannot return 0)
you are using size as different variables at different scopes (at main scope, and within deleteNode). This is pretty confusing although not strictly wrong.
in deleteNode, this sequence won't work:
else if (position == size-1) {
getNode(position - 1)->next = NULL;
delete getNode(position);
}
setting the next pointer on the node prior to position to NULL will interfere with the attempt to getNode(position) in the very next line, because it traverses the list based on next. The fix is to reverse these two lines.
Likewise, your last sequence in deleteNode won't work for a similar reason, because you are modifying the next pointers:
else {
getNode(position - 1)->next = getNode(position+1);
delete getNode(position); // this list traversal will skip the node to delete!
}
the solution here is like this:
else {
currentNode = getNode(position);
getNode(position - 1)->next = getNode(position+1);
delete currentNode;
}
I've also re-written the insertNode function incorporating the comment provided by #0x499602D2 .
Here's a modified version of your code that has your current sequence in main fixed:
#include <iostream>
using namespace std;
struct Node {
int data;
Node* next;
};
Node* head = NULL;
int size = 0;
Node* tail = NULL;
void printLinkedList() {
Node *search = head;
if (head == NULL) {
cout << "linkedlist is empty" << endl;
}
else {
while (search != NULL){
cout << search->data << endl;
search = search->next;
}
}
}
int sizeLinkedList() {
size = 0;
if (head->next != NULL){
size = 1;
Node* current = head;
while (current->next != NULL) {
current = current->next;
size = size + 1;
}
}
cout << size << endl;
return size;
}
Node *getNode(int position){
Node *current = head;
for (int i = 0; i<position; i++)
{
current = current->next;
}
return current;
}
void appendNode(int n) {
Node *newNode = new Node; //creating new node
newNode->data = n;
newNode->next = NULL;
size++;
if (head == NULL)
{
head = newNode;
return;
}
else {
Node *current = head;
while (current->next != NULL) {
current = current->next;
}
current->next = newNode;
}
}
void insertNode(int n, int position) {
Node *newNode = new Node;
newNode->data = n;
newNode->next = NULL;
if (position == 0){
newNode->next = head;
head = newNode;
}
else if (position == sizeLinkedList()) {
appendNode(n);
}
else {
Node *prevNode = getNode(position-1);
Node *nextNode = getNode(position);
prevNode->next = newNode;
newNode->next = nextNode;
}
}
void deleteNode(int position) {
Node *currentNode;
int my_size = sizeLinkedList();
if ((my_size == 0) || (position > my_size)) {
return;
}
if (position == 0) {
currentNode = head->next;
head = currentNode;
}
else if (position == size-1) {
delete getNode(position);
getNode(position - 1)->next = NULL;
}
else {
currentNode = getNode(position);
getNode(position - 1)->next = getNode(position+1);
delete currentNode;
}
}
//making a dynamic array only via pointers in VC++
void makeArray() {
int* m = NULL;
int n;
cout << "how many entries are there?"<<endl;
cin >> n;
m = new int[n];
int temp;
for (int x = 0; x < n; x++){
cout << "enter item:"<< x+1<< endl;
cin >> temp;
*(m + x) = temp;
}
for (int x = 0; x < n; x++){
cout << x+1 + ":" << "There is item: "<<*(m+x) << endl;
}
delete[]m;
}
int main() {
int x;
//makeArray();
appendNode(1);
appendNode(2);
appendNode(32);
appendNode(55);
appendNode(66);
insertNode(2, 0);
printLinkedList();
deleteNode(3);
printLinkedList();
sizeLinkedList();
}