reason why it doesn't works on visual 2019 - c++

I don't think there's a problem with coding grammar or composition. I drew it with my hands and checked it several times and found no particular problem. And I've tried this many times.
I tried to repeat over and over, but it just shuts down immediately without any output on the run window when I use the visual studio 2019 version. I've been Googling several times, but I can't find the solution I want.
Have I reinstall the visual program or have to manipulate extra options?
plz give some solutions
#include<iostream>
using namespace std;
#include<stdlib.h>
class Node {
public:
int data;
Node * next;
};
class Stack {
public:
Node *top;
Stack() {
top->next = NULL;
}
void push(int data);
int pop();
void show();
};
void Stack::push(int data)
{
Node *node = new Node;
node->data = data;
if (top->next == NULL) {
node->next = NULL;
top->next = node;
}
else {
node->next = top->next;
top->next = node;
}
}
int Stack::pop()
{
if (top-> next == NULL) {
cout << "stack empty" << endl;
return 0;
}
Node *temp = new Node;
temp = top->next;
int data = temp->data;
top->next = temp->next;
delete temp;
return data;
}
void Stack::show() {
Node *cur = new Node;
cur = top-> next;
while (cur != NULL) {
cout << cur-> data << "->";
cur = cur-> next;
}
}
int main() {
Stack s;
s.push(5);
s.push(1);
s.push(3);
s.show();
cout << endl;
cout << s.pop() << endl;
s.show();
return 0;
}

In your constructor
Stack() {
top->next = NULL;
}
top has never been given a value, so top->next is an error.
Looks to me that most of your code would be fixed if you replaced top->next with top throughout.
There's another error here
void Stack::show() {
Node *cur = new Node;
cur = top-> next;
You assign cur to a new node and then you forget about that and assign it to something else on the very next line. Just do this
void Stack::show() {
Node *cur = top-> next;
(but top-> next should really just be top as explained above).
and the same error here
Node *temp = new Node;
temp = top->next;
why assign a new node to temp if on the very next line you assign something else to temp?
Here's your code will all the bugs fixed (I think)
class Stack {
public:
Node *top;
Stack() {
top = NULL;
}
void push(int data);
int pop();
void show();
};
void Stack::push(int data)
{
Node *node = new Node;
node->data = data;
node->next = top;
top = node;
}
int Stack::pop()
{
if (top == NULL) {
cout << "stack empty" << endl;
return 0;
}
Node *temp = top;
int data = temp->data;
top = temp->next;
delete temp;
return data;
}
void Stack::show() {
Node *cur = top;
while (cur != NULL) {
cout << cur-> data << "->";
cur = cur-> next;
}
}

Related

Linked List insertion isn't working in for/while loop

I am learning DSA, and was trying to implement linked list but the insertion function that i wrote is not
working in a for or while loop, its not the same when i call that function outside the loop, it works that way. I am not able to figure it out, please someone help me.
#include <iostream>
class Node {
public:
int data;
Node *next;
Node(int &num) {
this->data = num;
next = NULL;
}
};
class LinkedList {
Node *head = NULL;
public:
void insert(int num) {
Node *tmp;
if (head == NULL) {
head = new Node(num);
tmp = head;
} else {
tmp->next = new Node(num);
tmp = tmp->next;
}
}
void printList() {
Node *tmp = head;
while (tmp) {
std::cout << tmp->data << " ";
tmp = tmp->next;
}
std::cout << std::endl;
}
void reverseList() {
Node *curr = head, *prev = NULL, *nextNode;
while (curr) {
nextNode = curr->next;
curr->next = prev;
prev = curr;
curr = nextNode;
}
head = prev;
}
};
int main() {
LinkedList list1;
// This is not working
int num;
while (num != -1) {
std::cin >> num;
list1.insert(num);
}
// This is working
// list1.insert(1);
// list1.insert(2);
// list1.insert(3);
// list1.insert(4);
// list1.insert(5);
list1.printList();
list1.reverseList();
list1.printList();
return 0;
}
I expect this after insertion
Edit:
although #Roberto Montalti solved this for me, but before that I tried passing incrementing value using a for loop which worked but as soon as I pull that cin out it crashes. can someone tell me what's happening under the hood?
for (int i = 1; i <= 10; i++)
{
list1.insert(i);
}
When inserting the nth item (1st excluded) tmp is a null pointer, i don't understand what you are doing there, you are assigning to next of some memory then you make that pointer point to another location, losing the pointer next you assigned before, you must keep track of the last item if you want optimal insertion. This way you are only assigning to some *tmp then going out of scope loses all your data... The best way is to just keep a pointer to the last inserted item, no need to use *tmp.
class LinkedList
{
Node *head = NULL;
Node *tail = NULL;
public:
void insert(int num)
{
if (head == NULL)
{
head = new Node(num);
tail = head;
}
else
{
tail->next = new Node(num);
tail = tail->next;
}
}
...
}
You need to loop until you reach the end of the list and then add the new node after that. Like this.
void insert(int num) {
Node *tmp = head;
if (head == NULL) {
head = new Node(num);
}
else {
while (tmp->next != NULL) {
tmp = tmp->next;
}
tmp->next = new Node(num);
}
}
first of all you need to define a node for each of the tail and head of the list as follows
Node *h;
Node *t;
you may also separate the Node from the LinkedList class so you can modify easily
class Node{
public:
int data;
Node *next;
Node(int data, Node* next);
~Node();
};
Node::Node(int data, Node* next)
{
this->data= data;
this->next= next;
}
Node::~Node(){}
}
after that you can try to add these functions to your LinkedList class
so it can deal with other special cases such empty list or full, etc..
void addToHead(int data){
Node *x = new Node(data,h);
h=x;
if(t==NULL){
t=x;
}
void addToTail(int data){
Node *x = new Node(data,NULL);
if(isEmpty()){
h=t=x;
}
else
{
t->next=x;
t=x;
}
}
now for the insert function try this after you implemented the Node class and the other functions,
void insert(int v){
if(h==nullptr){addToHead(v); return;}
if(h->data>=v) {addToHead(v);return;}
if(t->data<=v) {addToTail(v); return;}
// In this case there is at least two nodes
Node *k=h->next;
Node *p=h;
while(k != nullptr){
if(k->data >v){
Node *z =new Node(v,k);
p->next=z;
return;
}
p=k;
k=k->next;
}
}
the idea of making all of this is not lose the pointer when it goes through elements in the Linked List so you don't end up with a run time error.
I hope this can be useful to you.
There was an issue with your insert function.
Read about segmentation fault here https://www.geeksforgeeks.org/core-dump-segmentation-fault-c-cpp/#:~:text=Core%20Dump%2FSegmentation%20fault%20is,is%20known%20as%20core%20dump.
for a quick workaround you can use this
using namespace std;
#include <iostream>
class Node
{
public:
int data;
Node *next;
Node(int num)
{
this->data = num;
next = NULL;
}
};
class LinkedList
{
Node *head = NULL;
public:
void insert(int num)
{
Node *tmp= new Node(num);
tmp->next=head;
head=tmp;
}
void printList()
{
Node *tmp = head;
while (tmp)
{
std::cout << tmp->data << " ";
tmp = tmp->next;
}
std::cout << std::endl;
}
void reverseList()
{
Node *curr = head, *prev = NULL, *nextNode;
while (curr)
{
nextNode = curr->next;
curr->next = prev;
prev = curr;
curr = nextNode;
}
head = prev;
}
};
int main()
{
LinkedList list1;
// This is not working
int num,i=0,n;
cout<<"Type the value of n";
cin>>n;
while (i<n)
{
cin >> num;
cout<<num<<" "<<&num<<endl;
list1.insert(num);
i++;
}
list1.printList();
list1.reverseList();
list1.printList();
return 0;
}

How to use point to next node when deleting elements in C++

I have previously posted some part of this task here.
I am now implementing a method that removes an element at a given index. My code is
void remove(int index)
{
if (head != NULL)
{
Node *current = get_node(index);
Node *prev = get_node(index - 1);
Node *next = get_node(index + 1);
prev->next = current->next;
delete current;
}
}
however, I am facing this error message
libc++abi.dylib: terminating with uncaught exception of type
std::range_error: IndexError: Index out of range
Abort trap: 6
I am guessing the problem is the pointers, but I am not sure why this is not working. Anyone who can help?
I think you can handle corner cases like this:
#include <iostream>
using namespace std;
struct Node {
Node(int val) {
this->val = val;
}
struct Node * next;
int val;
};
class LinkedList {
public:
Node* head;
LinkedList() {
head = new Node(1);
Node * n1 = new Node(2);
head->next = n1;
Node * n2 = new Node(3);
n1->next = n2;
}
void remove(int index) {
if (head == NULL) {
return;
}
int pos = 0;
Node * cur = head;
Node *prev = NULL;
while (cur != NULL) {
if (pos == index) {
break;
}
pos++;
prev = cur;
cur = cur->next;
}
if (prev == NULL) {
head = head->next;
}
else {
prev->next = cur->next;
}
delete cur;
}
};
void print(Node * head){
cout << "Current linked list:\n";
while(head != NULL) {
cout << head->val << endl;
head = head->next;
}
cout << endl;
}
int main() {
LinkedList * list = new LinkedList();
print(list->head);
list->remove(0);
print(list->head);
list->remove(1);
print(list->head);
list->remove(0);
print(list->head);
}

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;
}

deleting a linked list node, C++ function not working

#include <iostream>
using namespace std;
class List {
public:
struct node {
int data;
node *next;
};
node* head = NULL;
node* tail = NULL;
node* temp = NULL;
node* prev = NULL;
public:
void addNum(int num) {
temp = new node;
temp->data = num;
temp->next = NULL;
if (head == NULL) {
head = temp;
tail = temp;
}
else {
tail->next = temp;
tail = temp;
}
}
void PrintList() {
temp = head;
while (temp != NULL) {
cout << temp->data << endl;
temp = temp->next;
}
}
void DelNum(int num) {
temp = head;
while (temp != NULL) {
if (temp->data == num) {
prev->next = temp->next;
free(temp);
}
temp = prev;
temp = temp->next;
}
}
};
int main() {
List list;
list.addNum(1);
list.addNum(2);
list.addNum(3);
list.addNum(4);
list.addNum(5);
list.addNum(6);
list.DelNum(3);
list.PrintList();
return 0;
}
What is wrong with my DelNum function? When I run the program nothing pops up. Doesn't matter what number I put in.
As mss pointed out the problem is in your DelNum() function where you assign temp = prev;. In your initialization you defined that node* prev = NULL; So, prev = NULL at the point when you assigned it to temp which caused segmentation fault when you try to use it like temp = temp->next;.
Two main problems are there in DelNum function:
first, when you are in while loop
, you should assign
prev = temp;
second, when you have found your target element, after deleting it you have to break out of the loop, which isn't done in your code
below is your corrected code( also correction of some other corner case in DelNum function ):
#include <iostream>
using namespace std;
class List {
public:
struct node {
int data;
node *next;
};
node* head = NULL;
node* tail = NULL;
node* temp = NULL;
node* prev = NULL;
public:
void addNum(int num) {
temp = new node;
temp->data = num;
temp->next = NULL;
if (head == NULL) {
head = temp;
tail = temp;
}
else {
tail->next = temp;
tail = temp;
}
cout<<num<<" is added \n";
}
void PrintList() {
temp = head;
while (temp != NULL) {
cout << temp->data << endl;
temp = temp->next;
}
}
void DelNum(int num) {
if(head==NULL)//empty
{
cout<<"empty linked list, can't be deleted\n";
return;
}
if(head->next==NULL)//means only one element is left
{
if(head->data==num)
{
node * fordelete=head;
head=NULL;
cout<<num<<"is deleted\n";
delete(fordelete);
}
else
{
cout<<"not found , can't be deleted\n";
}
return;
}
temp = head; // when more than one element are there
prev = temp;
while (temp != NULL) {
if (temp->data == num) {
prev->next = temp->next;
free(temp);
cout<<num<<" is deleted\n";
break;
}
prev= temp;
temp = temp->next;
}
if(temp==NULL)
{
cout<<"not found, can't be deleted\n";
}
}
};
int main() {
List list;
list.addNum(1);
list.addNum(2);
list.addNum(3);
list.addNum(4);
list.addNum(5);
list.addNum(6);
list.PrintList();
list.DelNum(3);
list.DelNum(7);
list.PrintList();
return 0;
}
I hope it will help you.

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;
}