I'm trying to create a linked list that can append/delete/display items. I got the header and the test complete, and it seems to have worked. It successfully appended, deleted, and displayed the results. However, immediately after the results were displayed, I get a runtime pop-up saying "Debug Assertion Failed! Expression:_BLOCK_TYPE_IS_VALID(pHead->nBlockUse)"
So I did some debugging, and obviously it's a memory leak (or at least I'm pretty sure it is). I swear my destructor was written correctly. My test works, the linked list works (plus it's member functions) works, so what am I doing wrong?
Here's my class declarations, default constructor, and destructor
template <typename T>
class Node
{
public:
T Value;
Node<T> *next;
Node(T nodeValue)
{
value = nodeValue;
next = NULL;
}
};
template <typename T>
class LinkedList
{
private:
Node<T> *head;
public:
LinkedList()
{ head = NULL; }
~LinkedList()
{
Node<T> *temp;
Node<T> *nextNode;
temp = head;
while (temp != NULL)
{
nextNode = temp->next;
delete temp;
temp = nextNode;
}
}
}
And here's the rest of the Linked List (even though it works but in case you ask)
void appendNode(T newValue)
{
Node<T> *newNode;
Node<T> *temp;
newNode = new Node<T>(newValue);
if (!head)
head = newNode;
else
{
temp = head;
while (temp->next)
temp = temp->next;
temp->next = newNode;
}
}
void deleteNode(T searchValue)
{
Node<T> *temp;
Node<T> *prev = NULL;
if (!head)
return;
if (head->value == searchValue)
{
temp = head->next;
delete head;
head = temp;
}
else
{
temp = head;
while (temp != NULL && temp->value != searchValue)
{
prev = temp;
temp = temp->next;
}
if (temp)
{
prev->next = temp->next;
delete temp;
}
}
}
void displayList() const
{
Node<T> *temp;
temp = head;
while (temp)
{
cout << temp->value << " ";
temp = temp->next;
}
}
Related
I am trying to code for deletion of a node with k as data of linked list. The below program is running fine, but it is not giving desired output if we have to delete the head node. For example, if the linked list is 98->6->1 and I have to delete 98, then the output which the program is showing is 0->6->1. Except for the deletion of the head node, it is working correctly for all other cases.
Below is the c++ code for the same.
#include <bits/stdc++.h>
using namespace std;
class Node
{
public :
int data;
Node* next;
};
Node * insert(Node* head, int data) {
Node* new_node= new Node();
new_node->data = data;
new_node->next = head;
head = new_node;
return head;
}
void deleteNode(Node *head, int key)
{
Node *temp = head;
Node *prev = NULL;
if(temp!=NULL && temp->data==key){
head = temp->next;
delete temp;
}
else{
while(temp!=NULL && temp->data!=key){
prev = temp;
temp = temp->next;
}
if(temp == NULL){
return;
}
prev->next = temp->next;
delete temp;
}
}
void display(Node * head) {
while(head != NULL)
{
cout<<head->data<<" ";
head = head->next;
}
}
int main() {
Node * head = NULL;
head = insert(head, 1);
head=insert(head,6);
head=insert(head,98);
deleteNode(head,98);
display(head);
return 0;
}
In deleteNode(), you are passing in the head node by value, so any modification made to it is not reflected back to the caller. You need to either return the new head, like you do with Insert(), or else you need to pass in the head by reference:
void deleteNode(Node* &head, int key)
The mistake in your code is that the head you are passing to deleteNode function is by value so the changes made to the head function is not displayed. The head in your function is not the same head in your main function it is just the copy of that head, so to apply the same change being applied to the head in deletenode function to the original head, you have to pass the address of the head(or pass by reference).
Editing in your code-
I have applied changes in deleteNode function first five lines and the third last line when you are passing value by reference deleteNode(&head,98);
Edited code-
#include <bits/stdc++.h>
using namespace std;
class Node
{
public :
int data;
Node* next;
};
Node * insert(Node* head, int data) {
Node* new_node= new Node();
new_node->data = data;
new_node->next = head;
head = new_node;
return head;
}
void deleteNode(Node **head, int key)
{
Node *temp = *head;
Node *prev = NULL;
if(temp!=NULL && temp->data==key){
*head = temp->next;
temp->next = NULL;
delete temp;
}
else{
while(temp!=NULL && temp->data!=key){
prev = temp;
temp = temp->next;
}
if(temp == NULL){
return;
}
prev->next = temp->next;
// temp->next = NULL;
delete temp;
}
}
void display(Node * head) {
while(head != NULL)
{
cout<<head->data<<" ";
head = head->next;
}
}
int main() {
Node * head = NULL;
head = insert(head, 1);
head=insert(head,6);
head=insert(head,98);
deleteNode(&head,98);
display(head);
return 0;
}
Now if you run the above code the output you will get after deleting node of value 98 will be 6->1.
Hope you will find it helpful.
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;
}
How do I make my program print the Linked List backwards? I got the printForward function working fine but the printBackwards function just doesn't seem to do anything. I think I'm on the right track but I'm a little stuck right now. I think the while loop isn't running because temp is NULL for some reason.
Any help would be great.
Thanks
List.h
#include <iostream>
using namespace std;
class LinkedList
{
private:
struct Node
{
int data;
Node * next;
Node * prev;
};
Node * head, *tail;
public:
LinkedList();
bool addAtBeginning(int val);
bool remove(int val);
void printForward() const;
void printBackward() const;
};
#endif
List.cpp
#include "List.h"
LinkedList::LinkedList()
{
head = NULL;
tail = NULL;
}
bool LinkedList::addAtBeginning(int val)
{
Node* temp;
temp = new Node;
temp->data = val;
temp->next = head;
head = temp;
return false;
}
bool LinkedList::remove(int val)
{
return false;
}
void LinkedList::printForward() const
{
Node* temp = head;
while (temp != NULL) {
cout << temp->data << " ";
temp = temp->next;
}
cout << endl;
}
void LinkedList::printBackward() const
{
Node* temp = tail;
while (temp != NULL) {
cout << temp->data << " ";
temp = temp->prev;
}
cout << endl;
}
app.cpp
#include "list.h"
int main()
{
LinkedList aList;
aList.addAtBeginning(3);
aList.addAtBeginning(10);
aList.addAtBeginning(1);
aList.addAtBeginning(7);
aList.addAtBeginning(9);
aList.addAtBeginning(12);
aList.printForward();
aList.printBackward();
system("pause");
return 0;
}
I find it a bit odd that you only have an addAtBeginning method, and no method to add at the end, the latter which I would consider to be normal use of a linked list. That being said, I think the immediate problem here is that you never assign the tail to anything. Try this version of addAtBeginning:
bool LinkedList::addAtBeginning(int val)
{
Node* temp;
temp = new Node;
temp->data = val;
temp->next = head;
if (head != NULL)
{
head->prev = temp;
}
if (head == NULL)
{
tail = temp;
}
head = temp;
return false;
`}
The logic here is that for the first addition to an empty list, we assign the head and tail to the initial node. Then, in subsequent additions, we add a new element to the head of the list, and then assign both the next and prev pointers, to link the new node in both directions. This should allow you to iterate the list backwards, starting with the tail.
Update addAtBeginning function with given:
bool LinkedList::addAtBeginning(int val)
{
Node* temp;
temp = new Node;
temp->data = val;
temp->prev = temp->next = NULL;
// If adding first node, then head is NULL.
// Then, set Head and Tail to this new added node
if(head == NULL){
// If this linked list is circular
temp->next = temp->prev = temp;
head = tail = temp;
}else{ // If we already have at least one node in the list
// If this linked list is circular
temp->prev = head->prev;
temp->next = head;
head->prev = temp;
head = temp;
}
return false;
}
But remember, if you copy this function with the parts that it makes this list circular, you will get an infinite loop. So, either change print function or dont copy that parts.
It's been a week since i started learning about linked list and i only managed to learn about singly linked list. So today i implemented the linked list which i learned in c++ and while i tried to run it the code goes into an infinite loop of some random numbers. I tried debugging the code but i coudn't find whats so ever is wrong with the code. The code is below. Help is appreciated.Thanks
#include <iostream>
using namespace std;
struct node{
int data;
node * next;
};
class singly{
private:
node * head,*tail;
public:
singly(){
head=NULL;
tail=NULL;
}
void createNode(int value){
node * temp = new node;
temp->data=value;
temp->next=NULL;
if(head==NULL){
head=temp;
tail=temp;
temp=NULL;
}
else{
tail->next=temp;
tail=temp;
}
}
void display(){
node * temp = new node;
head=temp;
while(temp!=NULL){
cout << temp->data << "\t" << endl;
temp->next=temp;
}
}
void insert_end(int value){
node*newnode = new node;
node*temp = new node;
newnode->data=value;
newnode->next=NULL;
temp=head;
while(temp->next!=NULL){
temp = temp->next;
}
temp->next=newnode;
}
void delete_node(){
node*current = new node;
node*previous = new node;
current = head;
while(current->next!=NULL){
previous=current;
current=current->next;
}
tail=previous;
previous->next=NULL;
delete current;
}
};
int main(){
singly lists;
lists.createNode(32);
lists.createNode(654);
lists.createNode(34);
lists.createNode(234);
cout<<"\n--------------------------------------------------\n";
cout<<"---------------Displaying All nodes---------------";
cout<<"\n--------------------------------------------------\n";
lists.display();
cout<<"\n--------------------------------------------------\n";
cout<<"-----------------Inserting At End-----------------";
cout<<"\n--------------------------------------------------\n";
lists.createNode(55);
lists.display();
cout<<"\n--------------------------------------------------\n";
cout<<"-----------------Deleing At End-------------------";
cout<<"\n--------------------------------------------------\n";
lists.delete_node();
lists.display();
}
The member function display does not make sense.
It overwtites the data member head with uninitialized newly created temp.
node * temp = new node;
head=temp;
so the function invokes undefined behavior.
The function can look like
void display()
{
for ( node * temp = head; temp != nullptr; temp = temp->next )
{
cout << temp->data << "\t";
}
}
Or it is better to define it the following way
std::ostream & display( std::ostream &os = std::cout )
{
for ( node * temp = head; temp != nullptr; temp = temp->next )
{
os << temp->data << "\t";
}
return os;
}
The data member insert_end is also wrong. It does not take into account that head and tail can be equalto nullptr and does not change them.
The function can be defined the following way
void insert_end(int value)
{
node *newnode = new node { value, nullptr };
if ( tail == nullptr )
{
head = tail = newnode;
}
else
{
tail = tail->next = newnode;
}
}
The member function delete_node firstly does not make sense for a singly-linked list and again is wrong and invokes undefined behavior. The function should remove the first node from the list.
Nevertheless if you want to remove the last node from the list then the function can look like
void delete_node()
{
if ( head != nullptr )
{
tail = nullptr;
node *current = head;
while ( current->next )
{
tail = current;
current = current->next;
}
if ( tail == nullptr )
{
head = tail;
}
else
{
tail->next = nullptr;
}
delete current;
}
}
For starters, display() is wrong. You want the update to be temp = temp->next; and it can also be initialized as node * temp = head hence not requiring the second line.
Your delete_node() can be re-written to:
if (head->next == NULL) // handles the case that it consists of 1 element
{
delete head;
head = NULL;
}
else
{
node *nextToEnd = head;
node *end = head->next;
while (end->next != NULL)
{
nextToEnd = end;
end = end->next;
}
delete end;
nextToEnd->next = NULL;
}
As stated in the comments, review the use of the new keyword
Hi could you please help me change this linked list into a doubly linked list ?
I would be very grateful for help :)
#include <iostream>
using namespace std;
template <class T>
struct node
{
T data;
node<T> *next;
node<T> *prev;
};
template <class T>
class Container
{
public:
//constructs a new empty Kontener
Container()
{
head = new node<T>;
head->next = head;
head->prev = head;
};
//constructs a new jp_list that is a copy of an existing list
Container(const Container<T>& rt_side)
{
head = new node<T>;
head->next = head;
head->prev = head;
node<T> *crt_ptr = rt_side.head->next;
while(crt_ptr != rt_side.head)
{
push_back(crt_ptr->data);
crt_ptr = crt_ptr->next;
}
};
//adds a data node to the front of the list
void push_front(T nw_data)
{
node<T> *temp = new node<T>;
temp->data = nw_data;
temp->next = head->next;
head->next->prev = temp;
temp->prev = head;
head->next = temp;
};
//adds a data node to the end of the list
void push_back(T nw_data)
{
node<T> *temp = new node<T>;
temp->data = nw_data;
head->prev->next = temp;
temp->prev = head->prev;
temp->next = head;
head->prev = temp;
};
//removes the first node and returns the data
T pop_front()
{
node<T> *temp = head->next;
T temp_data = head->next->data;
head->next = temp->next;
temp->next->prev = head;
delete temp;
return temp_data;
};
//removes the last node and returns the data
T pop_back()
{
node<T> *temp = head->prev;
T temp_data = head->prev->data;
head->prev = temp->prev;
temp->prev->next = head;
delete temp;
return temp_data;
};
//resturns the size of the list
int size()
{
int size = 0;
node<T> *crt_ptr; //pointer to current node
crt_ptr = head->next;
while(crt_ptr != head)
{
size += 1;
crt_ptr = crt_ptr->next; //advance to the next node then loop
}
return size;
};
//prints out all the data in the list
void display_all()
{
node<T> *crt_ptr = head->next;
for(int i = 0; crt_ptr != head; i++)
{
cout << "Node " << (i+1) << ": " << crt_ptr->data << endl;
crt_ptr = crt_ptr->next;
}
};
Container& operator= (const Container& rt_side)
{
if(this == &rt_side)
return *this;
node<T> *crt_ptr = head->next;
//empty this list so the rt_side can be coppied in
while(crt_ptr != head)
{
crt_ptr = crt_ptr->next;
pop_front();
}
crt_ptr = rt_side.head->next;
while(crt_ptr != rt_side.head)
{
push_back(crt_ptr->data);
crt_ptr = crt_ptr->next;
}
return *this;
};
virtual ~Container()
{
int list_size = size();
for(int i = 0; i < list_size; i++)
{
pop_front();
}
delete head;
};
private:
node<T> *head;
};
#endif
I am just a beginner so please help me :)
The tail would always point to the last item that was inserted into the list.
However, I do not think that having a tail pointer makes it necessarily a doubly linked list. A singly linked list can also have a tail pointer (however useless it might be). I believe you are asking to create a double ended doubly linked list.
You already have the next and previous pointers to enable the double link. All you have to do, is when you push something into the list, you need to make the tail pointer point to the node that is being added. Similarly, when removing a node, you need the tail pointer to point to tail's previous BEFORE deleting the last node.
* UPDATE *
Here is some code. I am assuming a double ended doubly linked list with two ends.
void push_front(T nw_data)
{
node<T> *temp = new node<T>;
temp->data = nw_data;
if(head == nullptr)
{
head = temp;
tail = temp;
}
else if(head == tail)
{
head->next = temp;
temp->prev = head;
tail = temp;
}
else
{
temp->next = head->next;
head->next->prev = temp;
temp->prev = head;
head->next = temp;
}
};
//adds a data node to the end of the list
void push_back(T nw_data)
{
node<T> *temp = new node<T>;
temp->data = nw_data;
if(head == nullptr)
{
head = temp;
tail = temp;
}
else if(head == tail)
{
head->next = temp;
temp->prev = head;
tail = temp;
}
else
{
temp->prev = tail;
tail->next = temp;
tail = temp;
}
};
T pop_back()
{
node<T> *temp = tail;
T temp_data = tail->data;
tail = tail->prev;
tail->next = null;
delete temp;
return temp_data;
};
* UPDATE * Copy Constructor
In your copy constructor, if the push_back sets the tail, then all you need to do is to push_back the nodes like you are doing. head->next = head and head->prev = head makes the linked list cyclical.
Container(const Container<T>& rt_side)
{
this->head = rt_side.head;
node<T> * crt_ptr = rt_side.head->next;
while (crt_ptr != null)
{
push_back(crt_ptr->data);
crt_ptr = crt_ptr->next;
}
};