Linked list search function not working properly - c++

I am making a LinkedList class in C++ with its methods, like adding nodes, traversing, and searching. When implementing the search function, it seems not working properly because it does not find the value in linked list when in fact it is inside the linked list. The code is shown below.
#include <iostream>
class Node {
public:
int value;
Node* next;
Node(int value, Node* next) {
this->value = value;
this->next = next;
}
};
class LinkedList {
public:
Node* head;
Node* tail;
LinkedList() {
this->head = nullptr;
this->tail = nullptr;
}
LinkedList(Node* node) {
this->head = node;
this->tail = node;
}
void addNodeFront(Node* node) {
if(head==nullptr && tail==nullptr) {
this->head = node;
this->tail = node;
return;
}
this->tail = this->head;
this->head = node;
node->next = tail;
}
void addNodeBack(Node* node) {
if(head==nullptr && tail==nullptr) {
this->head = node;
this->tail = node;
return;
}
this->tail->next = node;
this->tail = node;
}
void addNodeAfterNode(Node* prevNode, Node* node) {
node->next = prevNode->next;
prevNode->next = node;
}
bool searchVal(int val) {
while(this->head != nullptr) {
if(this->head->value == val) return true;
this->head = this->head->next;
}
return false;
}
void deleteNode(Node* node) {
Node* prevNode = this->head;
while(prevNode->next != node) {
}
}
void traverseLinkedList() {
while(this->head!=nullptr) {
std::cout << this->head->value << "->";
this->head = this->head->next;
}
std::cout << "\n";
}
void sortLinkedList() {
}
};
int main() {
Node node1(2,nullptr);
Node node2(4,nullptr);
Node node3(3,nullptr);
LinkedList ls;
ls.addNodeFront(&node1);
ls.addNodeBack(&node3);
ls.addNodeAfterNode(&node3, &node2);
ls.traverseLinkedList();
if(ls.searchVal(4)) std::cout << "value found\n";
else std::cout << "value not found\n";
}
When I call the searchVal() function inside the main function it outputs value not found while value 4 is inside the linked list. What is wrong with my code?

When I call the searchVal() function inside the main function it
outputs value not found while value 4 is inside the linked list. What
is wrong with my code?
Just before you call searchVal(4) you call traverseLinkedList(), and traverseLinkedList() is implemented in such a way that when it returns, this->head will be NULL, which means that at that point your linked list is empty (and you have leaked memory). You'll want to modify traverseLinkedList() and searchVal() to not change the value of this->head (or any other member-variables of the LinkedList object) so that they don't modify the state of the list as a side effect.

Related

Number of element inside linked list

I want to save the number of element inside an instance of linked list class object. From the code below everytime I call addNodeFront() or addNodeBack() function, member variable len should be incremented by 1. But, when I run the code, the getLen function only return 1, while the linked list has 2 element. What should I fix from the my code?
#include <iostream>
class Node {
public:
int value;
Node* next;
Node(int value, Node* next) {
this->value = value;
this->next = next;
}
};
class LinkedList {
public:
Node* head;
Node* tail;
int len = 0;
LinkedList() {
this->head = nullptr;
this->tail = nullptr;
}
LinkedList(Node* node) {
this->head = node;
this->tail = node;
}
int getLen() {
return len;
}
void addNodeFront(Node* node) {
if(head==nullptr && tail==nullptr) {
this->head = node;
this->tail = node;
return;
}
Node* secondFirst = this->head;
this->head = node;
node->next = secondFirst;
this->len++;
}
void addNodeBack(Node* node) {
if(head==nullptr && tail==nullptr) {
this->head = node;
this->tail = node;
return;
}
this->tail->next = node;
this->tail = node;
this->len++;
}
void addNodeAfterNode(Node* prevNode, Node* node) {
if(prevNode == this->tail) {
this->tail = node;
prevNode->next = node;
return;
}
node->next = prevNode->next;
prevNode->next = node;
}
bool searchVal(int val) const {
Node* s = this->head;
while(s != nullptr) {
if(s->value == val) return true;
s = s->next;
}
return false;
}
void deleteNodeFront() {
if(this->head==this->tail) {
this->head = nullptr;
this->tail = nullptr;
return;
}
this->head = this->head->next;
}
void deleteNodeBack() {
Node* secondLast = this->head;
if(this->head==this->tail) {
this->head = nullptr;
this->tail = nullptr;
return;
}
while(secondLast->next != this->tail) {
secondLast = secondLast->next;
}
secondLast->next = nullptr;
this->tail = secondLast;
}
void deleteNodeMiddle(Node* node) {
if(node==this->head || node==this->tail) return;
Node* prevNode = this->head;
while(prevNode->next != node) {
prevNode = prevNode->next;
}
prevNode->next = prevNode->next->next;
}
void traverseLinkedList() {
Node* t = this->head;
if(head==nullptr && tail==nullptr) std::cout << "Empty Linked List";
while(t != nullptr) {
std::cout << t->value << "->";
t = t->next;
}
std::cout << "\n";
}
};
int main() {
Node node1(2,nullptr);
Node node4(4,nullptr);
LinkedList ls;
ls.addNodeFront(&node1);
ls.addNodeFront(&node4);
std::cout << ls.getLen() << std::endl;
ls.traverseLinkedList();
}
In the following function:
LinkedList(Node* node)
{
this->head = node;
this->tail = node;
}
Just add one of the following lines:
len++; //1
len = 1; //2
So the updated function:
LinkedList(Node* node)
{
this->head = node;
this->tail = node;
len++; //1
len = 1; //2
}
This is because as the head node and the tail node = node now, that means there is a node in the linked list, so we should add 1 to len.

C++ linked list implementation, goes to infinite loop while traversing. Guessing something is wrong with the contructors

I'm new to C++. I'm trying to implement a linked list. The output goes to an infinite loop when the traverse function is called(output shown at the bottom). Had no errors when I used 'new' in the insertNodeAtEnd function instead of contructors, but I read up that it's generally not a good practice in C++ and it's better to get accustomed to using constructors.
What am I doing wrong?
#include <iostream>
struct Node
{
int data;
Node *next;
Node(int data)
{
this->data = data;
this->next = NULL;
}
~Node() {}
};
class LinkedList
{
public:
LinkedList()
{
std::cout << "Linked list created \n";
}
static Node *head;
static Node *tail;
static int numberOfNodes;
static int getNumberOfNodes()
{
return numberOfNodes;
}
static void insertNodeAtEnd(int data)
{
Node newNode(data);
if (head == NULL)
{
head = tail = &newNode;
return;
}
tail->next = &newNode;
tail = &newNode;
numberOfNodes++;
return;
}
static void traverse()
{
if (numberOfNodes == 0)
{
std::cout << "Linked list is empty \n";
}
Node *curr = head;
while (curr != NULL)
{
std::cout << curr->data << std::endl;
curr = curr->next;
}
return;
}
~LinkedList()
{
std::cout << "Linked list destroyed \n";
}
};
Node *LinkedList::head = NULL;
Node *LinkedList::tail = NULL;
int LinkedList::numberOfNodes = 0;
int main()
{
LinkedList linkedlist;
linkedlist.insertNodeAtEnd(40);
linkedlist.insertNodeAtEnd(50);
linkedlist.insertNodeAtEnd(60);
linkedlist.insertNodeAtEnd(70);
linkedlist.traverse();
}
And here's the output. (Infinite loop, had to terminate in the console.)
Linked list created
70
70
70
70
70
70
70
Here:
static void insertNodeAtEnd(int data)
{
Node newNode(data);
if (head == NULL)
{
head = tail = &newNode;
return;
}
tail->next = &newNode;
tail = &newNode;
numberOfNodes++;
return;
}
newNode is a function local variable. Its lifetimes ends when the function returns. The pointers you store are dangling. When you dereference them later you invoke undefined behavior.
To dynamically allocate the nodes, such that they persist you can do
Node* newNode = new Node(data);
It is not clear why all members of LinkedList are declared static. The effect is basically that you can only have one linked list, because a second one would share all members.
I got it to work by instead creating a new Node rather than directly instantiating one. What happens in your version is that the created node is destroyed while by creating a new one it will remain valid until explicitly deleted
#include <iostream>
struct Node
{
int data;
Node *next;
Node(int data)
{
this->data = data;
this->next = NULL;
}
~Node() {}
};
class LinkedList
{
public:
LinkedList()
{
std::cout << "Linked list created \n";
}
static Node *head;
static Node *tail;
static int numberOfNodes;
static int getNumberOfNodes()
{
return numberOfNodes;
}
static void insertNodeAtEnd(int data)
{
Node* newNode = new Node(data);
if (head == NULL)
{
head = tail = newNode;
return;
}
tail->next = newNode;
tail = newNode;
numberOfNodes++;
return;
}
static void traverse()
{
if (numberOfNodes == 0)
{
std::cout << "Linked list is empty \n";
}
Node *curr = head;
while (curr != NULL)
{
std::cout << curr->data << std::endl;
curr = curr->next;
}
return;
}
~LinkedList()
{
std::cout << "Linked list destroyed \n";
}
};
Node *LinkedList::head = NULL;
Node *LinkedList::tail = NULL;
int LinkedList::numberOfNodes = 0;
int main()
{
LinkedList linkedlist;
linkedlist.insertNodeAtEnd(40);
linkedlist.insertNodeAtEnd(50);
linkedlist.insertNodeAtEnd(60);
linkedlist.insertNodeAtEnd(70);
linkedlist.traverse();
}

Linked List implementation of a Stack

Fairly new to implementing stacks and was looking for some possible feedback. My code gives the correct output, but I know this doesn't always mean it is working as it is suppose to. I chose to take the approach that implementing a stack using a linked list was essentially the same as your regular linked list implementation except that all the operations are done on the end of the list. I was not too sure if this approach was correct, but it followed the first in last out approach, and has the same complexity for access & search (O(n)) and insertion and deletion O(1). Such as pop() would just be deleting a node from the end of the linked list, and push() would just be appending a node to the end of the linked list. I have pasted my code below with comments within them explaining what I am doing or trying to do (if it is incorrect).
#include <iostream>
struct Node{
int data;
Node* next;
};
bool isEmpty(Node** stack){
if(*stack == NULL){
return true;
}
return false;
}
void push(Node** stack, int data){
Node* new_node = new Node();
new_node->data = data;
new_node->next=NULL;
// stack similar to "head"
if(isEmpty(&(*stack))){
*stack = new_node;
return;
}
Node* temp = *stack;
while(temp->next != NULL){
temp = temp->next;
}
temp->next = new_node;
}
void pop(Node** stack){
// checking if stack is empty
if(isEmpty(&(*stack))){
std::cout<<"Stack underflow"<<std::endl;
return;
}
Node* deleteMe = *stack;
// if at the first element in the stack
if(deleteMe->next == NULL){
*stack = (*stack)->next;
delete deleteMe;
return;
}
while(deleteMe->next != NULL){
if(deleteMe->next->next==NULL){
// saving the current location of the node before the node which I want to delete
Node* temp = deleteMe;
// updating the deleteMe pointer to the node which I want to delete
deleteMe = deleteMe->next;
// setting the current node before the deleteMe node to point to NULL instead of the node which I want to delete
temp->next = NULL;
delete deleteMe;
return;
}
deleteMe = deleteMe->next;
}
}
void printList(Node* stack){
Node* temp = stack;
while(temp!=NULL){
std::cout<<temp->data<<" ";
temp = temp->next;
}
std::cout<<"\n";
}
int top(Node** stack){
Node* top = *stack;
while(top->next!=NULL){
top = top->next;
}
return top->data;
}
int main(){
Node* stack = NULL;
// testing implementation below
push(&stack,10);
std::cout<<top(&stack)<<std::endl;
push(&stack,20);
std::cout<<top(&stack)<<std::endl;
push(&stack,30);
push(&stack,40);
printList(stack);
std::cout<<top(&stack)<<std::endl;
pop(&stack);
pop(&stack);
push(&stack,40);
std::cout<<top(&stack)<<std::endl;
}
Your implementation looks fine, one additional improvement can be done by maintaining head and tail pointer so that you can remove 1st and last element as needed. Here is example c++ code.
#include <iostream>
using namespace std;
template <class T> class node {
public:
node<T>() {}
~node<T>() {}
T data;
node<T> *next;
};
template <class T> class linked_list {
public:
linked_list<T>() : head(NULL), tail(NULL) {}
~linked_list<T>() {}
virtual void addFirst(T data) {
node<T> *n = new node<T>();
if (head == NULL)
tail = n;
n->data = data;
n->next = head;
head = n;
size++;
}
virtual void addLast(T data) {
node<T> *n = new node<T>();
n->data = data;
if (tail == NULL) {
head = n;
} else {
tail->next = n;
}
n->next = NULL;
tail = n;
}
virtual void reverse() {
if ((head == NULL) || (head->next == NULL))
return;
node<T> *current = head;
node<T> *previous = NULL;
node<T> *next = current->next;
tail = current;
while (current) {
next = current->next;
current->next = previous;
previous = current;
current = next;
}
head = previous;
}
virtual void print_nodes() {
node<T> *temp = head;
while (temp) {
cout << temp->data << " " << flush;
temp = temp->next;
}
cout << endl;
}
virtual void removeLast() {
node<T> *temp = head;
while (temp->next->next) {
temp = temp->next;
}
tail = temp;
delete temp->next;
temp->next = NULL;
}
virtual void removeFirst() {
node<T> *temp = head;
head = head->next;
delete temp;
}
private:
node<T> *head;
node<T> *tail;
uint32_t size;
};
int main(int argc, const char *argv[]) {
linked_list<uint32_t> *llist = new linked_list<uint32_t>();
llist->addLast(1);
llist->addFirst(5);
llist->addFirst(10);
llist->addFirst(15);
llist->addFirst(20);
llist->addLast(30);
llist->addFirst(40);
llist->print_nodes();
llist->reverse();
llist->print_nodes();
llist->removeLast();
llist->print_nodes();
llist->removeFirst();
llist->print_nodes();
return 0;
}

A normal Linked List

I decided to practice my linked-list knowledge, and decided to create one in C++!
I ran this code on two different online compilers - one worked, and the other is giving me a segfault. I cannot figure out what the problem is within my code, and am wondering if you can help me.
#include <iostream>
using namespace std;
struct Node {
int val;
Node *next;
Node(int val){
this->val = val;
this->next = NULL;
}
};
class LinkedList {
public:
Node *head;
void insertAtHead(Node *temp)
{
if (head == NULL)
{
head = temp;
}
else
{
temp->next = head;
head = temp;
}
}
void printList()
{
Node *temp = head;
while (temp != NULL)
{
cout << temp->val << endl;
temp = temp->next;
}
}
void insertAtBack(Node *temp)
{
if (head == NULL)
{
head = temp;
return;
}
Node *current = head;
while (current->next != NULL){
current = current->next;
}
current->next = temp;
}
void deleteNode(Node *temp)
{
if (head == NULL)
{
cout << "Empty List";
return;
}
if (head->val == temp->val)
{
head = head->next;
return;
}
Node *current = head;
while (current->next != NULL)
{
if (current->next->val == temp->val)
{
current->next = current->next->next;
return;
}
current = current->next;
}
}
};
int main()
{
Node *temp = new Node(10);
Node *temp2 = new Node(4);
Node *temp3 = new Node(17);
Node *temp4 = new Node(22);
Node *temp5 = new Node(1);
LinkedList x;
x.insertAtHead(temp);
x.insertAtHead(temp2);
x.insertAtBack(temp3);
// x.insertAtBack(temp4);
// x.insertAtBack(temp5);
// x.deleteNode(temp);
x.printList();
return 0;
}
The problem I am encountering is when I use the insertAtBack() method. It gives me a segfault, but I do not see what's wrong with the logic. It is pretty straight forward. The insertAtFront() method works, but once I call insertAtBack() my code fails.
make sure to initialize Node *head to NULL.
After insert temp(which is value 10), temp->next value becomes undefined value, because Node *head is undefined value.
Your LinkedList class is not initializing its head member. You need to add a constructor to initialize head to NULL.
Also, the class is leaking memory, as there is no destructor to free the nodes when a LinkedList instance is destroyed, and deleteNode() doesn't free the node being removed, either.
Try something more like this:
#include <iostream>
using namespace std;
struct Node
{
int val;
Node *next;
Node(int val) : val(val), next(NULL) { }
};
class LinkedList
{
private:
Node *head;
// if you are NOT using C++11 or later, add these
// until you are reading to tackle copy semantics!
/*
LinkedList(const LinkedList &);
LinkedList& operator=(const LinkedList &);
*/
public:
LinkedList() : head(NULL) {} // <-- add this!
~LinkedList() // <-- add this!
{
Node *current = head;
while (current)
{
Node *next = current->next;
delete current;
current = next;
}
}
void insertAtHead(Node *temp)
{
if (!head)
{
head = temp;
}
else
{
temp->next = head;
head = temp;
}
}
void printList()
{
Node *current = head;
while (current)
{
cout << current->val << endl;
current = current->next;
}
}
void insertAtBack(Node *temp)
{
if (!head)
{
head = temp;
return;
}
Node *current = head;
while (current->next) {
current = current->next;
}
current->next = temp;
}
void deleteNode(Node *temp)
{
if (!head)
{
cout << "Empty List";
return;
}
if (head == temp)
{
head = temp->next;
delete temp;
return;
}
Node *current = head;
while (current->next)
{
if (current->next == temp)
{
current->next = temp->next;
delete temp;
return;
}
current = current->next;
}
}
// if you ARE using C++11 or later, add these until
// you are reading to tackle copy and move semantics!
/*
LinkedList(const LinkedList &) = delete;
LinkedList(LinkedList &&) = delete;
LinkedList& operator=(const LinkedList &) = delete;
LinkedList& operator=(LinkedList &&) = delete;
*/
};
int main()
{
Node *temp = new Node(10);
Node *temp2 = new Node(4);
Node *temp3 = new Node(17);
Node *temp4 = new Node(22);
Node *temp5 = new Node(1);
LinkedList x;
x.insertAtHead(temp);
x.insertAtHead(temp2);
x.insertAtBack(temp3);
// x.insertAtBack(temp4);
// x.insertAtBack(temp5);
// x.deleteNode(temp);
x.printList();
return 0;
}
Which can then be simplified further:
#include <iostream>
using namespace std;
struct Node
{
int val;
Node *next;
Node(int val, Node *next = NULL) : val(val), next(next) { }
};
class LinkedList
{
private:
Node *head;
// if you are NOT using C++11 or later, add these
// until you are reading to tackle copy semantics!
/*
LinkedList(const LinkedList &);
LinkedList& operator=(const LinkedList &);
*/
public:
LinkedList() : head(NULL) {} // <-- add this!
~LinkedList() // <-- add this!
{
Node *current = head;
while (current)
{
Node *next = current->next;
delete current;
current = next;
}
}
Node* insertAtHead(int value)
{
Node *temp = new Node(value, head);
if (!head)
head = temp;
return temp;
}
void printList()
{
Node *current = head;
while (current)
{
cout << current->val << endl;
current = current->next;
}
}
Node* insertAtBack(int value)
{
Node **current = &head;
while (*current)
current = &((*current)->next);
*current = new Node(value);
return *current;
}
/*
void deleteNode(Node *temp)
{
Node *current = head, *previous = NULL;
while (current)
{
if (current == temp)
{
if (previous)
previous->next = temp->next;
if (head == temp)
head = temp->next;
delete temp;
return true;
}
previous = current;
current = current->next;
}
cout << "Not found" << endl;
return false;
}
*/
bool deleteValue(int value)
{
Node *current = head, *previous = NULL;
while (current)
{
if (current->val == value)
{
if (previous)
previous->next = temp->next;
if (head == temp)
head = temp->next;
delete temp;
return true;
}
previous = current;
current = current->next;
}
cout << "Not found" << endl;
return false;
}
// if you ARE using C++11 or later, add these until
// you are reading to tackle copy and move semantics!
/*
LinkedList(const LinkedList &) = delete;
LinkedList(LinkedList &&) = delete;
LinkedList& operator=(const LinkedList &) = delete;
LinkedList& operator=(LinkedList &&) = delete;
*/
};
int main()
{
LinkedList x;
x.insertAtHead(10);
x.insertAtHead(4);
x.insertAtBack(17);
// x.insertAtBack(22);
// x.insertAtBack(1);
// x.deleteValue(10);
x.printList();
return 0;
}

simple linked list delete fails

I'm learning C++, I try to implement simple singly linked list but the delete node part fails. I could not comprehend why this basic delete_node part is failing. It seems prev->set_next line in delete_node method does not working correctly. I tried to debug it too but failed to spot the error.
using namespace std; //ignore it for simplicity
class Node {
int data;
Node *next;
public:
Node() {}
void set_data(int a_data)
{
data = a_data;
}
void set_next(Node *a_next)
{
next = a_next;
}
int get_data()
{
return data;
}
Node* get_next()
{
return next;
}
};
class List {
Node *head;
public:
List()
{
head = NULL;
}
void print_list();
void append_node(int data);
void delete_node(int data);
};
void List::print_list()
{
Node *temp = head;
if(temp == NULL)
{
cout << "empty" << endl;
return;
}
if(temp->get_next() == NULL)
{
cout << temp->get_data() << "--->";
cout << "NULL" << endl;
}
else
{
do
{
cout << temp->get_data() << "+++>";
temp = temp->get_next();
} while(temp != NULL);
cout << "NULL" << endl;
}
}
void List::append_node(int data)
{
Node *new_node = new Node();
new_node->set_data(data);
new_node->set_next(NULL);
Node *temp = head;
if(temp != NULL)
{
while(temp->get_next()!=NULL)
{
temp = temp->get_next();
}
temp->set_next(new_node);
}
else
{
head = new_node;
}
}
void List::delete_node(int data)
{
Node *temp = head;
if(temp == NULL)
{
return;
}
else
{
Node *prev = NULL;
do
{
prev = temp;
if(temp->get_data() == data)
{
prev->set_next(temp->get_next());
delete temp;
break;
}
temp = temp->get_next();
} while(temp!=NULL);
}
}
int main()
{
List list;
list.append_node(10);
list.append_node(20);
list.append_node(30);
list.append_node(40);
list.append_node(50);
list.append_node(60);
list.delete_node(30); //
list.print_list();
return 0;
}
valgrind gives me following error.
==22232== Invalid read of size 8
==22232== at 0x400D38: Node::get_next() (20_1.cpp:25)
==22232== by 0x400A5E: List::print_list() (20_1.cpp:62)
==22232== by 0x400C6C: main (20_1.cpp:127)
==22232== Address 0x5abdd28 is 8 bytes inside a block of size 16 free'd
==22232== at 0x4C2F24B: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==22232== by 0x400BA8: List::delete_node(int) (20
Lets take a closer look at these lines from the List::delete_node function
prev = temp;
if(temp->get_data() == data)
{
prev->set_next(temp->get_next());
delete temp;
break;
}
The first one make prev point to the very same node that temp is pointing to. After this prev == temp is true.
So when you do
prev->set_next(temp->get_next());
it is the same as
temp->set_next(temp->get_next());
That is, you make temp->next point to temp->next which doesn't change it at all. You never unlink the node from the list, but you do delete it. That makes your printing of the list invalid, as you will dereference a deleted node.
As a simple solution, you could do something like this:
if (head->get_data() == data)
{
// Special case: Head node is the one we want to delete
Node* old_head = head;
// Make the head be the second node in the list, if any
head = head->get_next();
// Delete the old head
delete old_head;
}
else
{
// We know it's not the head node of the list, use the "next" to find it
for (Node* node = head; node->get_next() != 0; node = node->get_next())
{
if (node->get_next()->get_data() == data)
{
// It's the "next" node we want to remove
Node* old_next = node->get_next();
// Unlink the node
node->set_next(node->get_next()->get_next());
delete old_next;
break;
}
}
}
The problem is that at the beginning of your do / while loop pointers temp and prev point to the same Node. Hence, you re-point the node, and then delete it right away.
A better approach is to not use prev at all. Get next, see if its data matches the one being deleted. If it does, "bypass" and delete next. Otherwise, move on to the next node until you hit NULL:
void List::delete_node(int data) {
if(head == NULL) {
return;
}
if (head->get_data() == data) {
Node *toDelete = head;
head = head->get_next();
delete toDelete;
return;
}
Node *temp = head;
for ( ; ; ) {
Node *next = temp->get_next();
if (next == null) {
break;
}
if (next->get_data() == data) {
temp->set_next(next->get_next());
delete next;
break;
}
temp = temp->get_next();
}
}
The exact working solution is
void List::delete_node(int data)
{
Node *temp = head;
Node *prev = NULL;
//first check whether its a parent element or not
if(temp && temp->get_data() == data){
head = head->get_next();
delete temp;
}
else{
while (temp){
if (temp->get_data() == data){
if (prev)
prev->set_next(temp->get_next());
delete temp;
return;
}
prev = temp;
temp = temp->get_next();
}
}
}
This even works for deleting head node
I see a number of problems with your code.
Your Node constructors is not initializing any of the Node members.
Your List class is missing a destructor to free any allocated nodes.
Your print_list() and append_node() implementations are a little more verbose than they need to be.
But, most importantly, regarding your particular question, your list's delete_node() method is not managing its prev variable correctly. prev is always pointing at the current node that is being looked at, not at the previous node that was already looked at. So you are not actually updating your links correctly when removing a node. You are also not updating the list's head member if the node being removed is the head node.
Try something more like this instead:
class Node;
class List {
Node *head;
public:
List();
~List();
void print_list();
void append_node(int data);
void delete_node(int data);
};
class Node {
int data;
Node *next;
public:
Node(int a_data = 0, Node *a_next = NULL);
void set_data(int a_data);
void set_next(Node *a_next);
int get_data();
Node* get_next();
friend class List;
};
Node::Node(int a_data, Node *a_next)
: data(a_data), next(a_next)
{
}
void Node::set_data(int a_data)
{
data = a_data;
}
void Node::set_next(Node *a_next)
{
next = a_next;
}
int Node::get_data()
{
return data;
}
Node* Node::get_next()
{
return next;
}
List::List()
: head(NULL)
{
}
List::~List()
{
Node *temp = head;
while (temp)
{
Node *next = temp->get_next();
delete temp;
temp = next;
}
}
void List::print_list()
{
Node *temp = head;
if (!temp)
{
cout << "empty" << endl;
return;
}
do
{
cout << temp->get_data();
temp = temp->get_next();
if (!temp) break;
cout << "+++>";
}
while (true);
cout << "--->NULL" << endl;
}
void List::append_node(int data)
{
Node **temp = &head;
while (*temp) temp = &((*temp)->next);
*temp = new Node(data);
}
void List::delete_node(int data)
{
Node *temp = head;
Node *prev = NULL;
while (temp)
{
if (temp->get_data() == data)
{
if (prev)
prev->set_next(temp->get_next());
if (temp == head)
head = temp->get_next();
delete temp;
return;
}
prev = temp;
temp = temp->get_next();
}
}
int main()
{
List list;
list.append_node(10);
list.append_node(20);
list.append_node(30);
list.append_node(40);
list.append_node(50);
list.append_node(60);
list.delete_node(30); //
list.print_list();
return 0;
}