Inserting Pop Functionality using link lists - c++

I'm new to data structures and started using C++ after a long time. After going through a few diagrams, I decided to create my own linked list (implementing a simple pop function).
Here is the code I came up with:
#include <iostream>
using namespace std;
typedef struct node
{
int data;
node *next;
}node;
node *start;
int count_1 = 0;
void push(int x)
{
node *n = new node;
node *temp;
temp = n;
temp->data = x;
temp->next = start;
start = temp;
count_1++;
}
void ShowStack()
{
for (int i=0; i<count_1; i++)
{
node *temp = start;
cout<<temp->data<<endl;
temp = temp->next;
}
}
int main()
{
node *n = new node;
start = n;
n->data = 6;
n->next = NULL;
count_1++;
ShowStack();
push(7);
push(8);
push(9);
push(20);
//count_1=20;
ShowStack();
return 0;
}
It's very basic but I seem to be facing a problem; when I run the program the first output is '6' which is correct but after that, all the values are 20 (even if I hard-set the counter to some hard-coded value like 20 (see code). I'd appreciate if someone can explain what's wrong with this implementation (besides the fact that the program is very messy). Also, what steps would/should I take to get the correct 'pop' functionality.

In your ShowStack() function, move "node *temp = start;" outside the loop.

Related

Error "Abort signal from abort(3) (sigabrt) " for linked list in C++

The following code is for a basic circular linked list, but when one inputs a large value for n(e.g 8 digits) it throws the "abort signal from abort(3) (sigabrt)" error. I'm not sure what it means and would love some guidance about fixing this with regard to my code.
Thank you!
#include<bits/stdc++.h>
using namespace std;
//First I created a structure for a node in a circular linked list
struct Node
{
int data;
struct Node *next;
};
// function to create a new node
Node *newNode(int data)
{
Node *temporary = new Node;
temporary->next = temporary;
temporary->data = data;
return temporary;
}
// This function finds the last man standing in
//the game of elimination
void gameOfElimination(int m, int n)
{
//first I created a circular linked list of the size which the user inputted
Node *head = newNode(1);
Node *prev = head;
//this loop links the previous node to the next node, and so on.
for (int index = 2; index <= n; index++)
{
prev->next = newNode(index);
prev = prev->next;
}
prev->next = head; //This connects the last and first nodes in our linked list together.
//when only one node is left, which is our answer:
Node *ptr1 = head, *ptr2 = head;
while (ptr1->next != ptr1)
{
int count = 1;
while (count != m)
{
ptr2 = ptr1;
ptr1 = ptr1->next;
count++;
}
/* Remove the m-th node */
ptr2->next = ptr1->next;
ptr1 = ptr2->next;
}
printf ("%d\n ",
ptr1->data);
}
//main program which takes in values and calls the function:
int main()
{
int n, p;
cin>>n>>p;
int m=p+1;
gameOfElimination(m, n);
return 0;
}
SIGABRT is generally issued when there are memory issues (heap corruption being quite common). In your code, I see only the new() operator being called, but you aren't deleting any unused nodes from your linked list! Seems like you're exhausting the memory allocated to your process.
You might be running out of memory. Check your ram usage during the execution of your program, that might lead to something.
enter code here
#include<bits/stdc++.h>
using namespace std;
class Node{
public:
int data;
Node *next;
};
void traverse(Node *head)
{
while (head != NULL)
{
/* code */
cout<<head->data<<"->";
head = head->next;
}
cout<<"NULL"
}
int main()
{
Node *head = new Node();
Node *second = new Node();;
Node *third = new Node();;
Node *fourth = new Node();;
head->data = 5;
head->next = second;
//cout<<head->data;
second->data=10;
second->next=third;
third->data = 15;
third->next = fourth;
fourth->data = 20;
fourth->next= NULL;
traverse(head);
return 0;
}```

Creating Linked List using For Loop (c++)

I was trying to create a linked list using a for loop but the 'new' in the for loop in the create() method didn't quite allocate a new slot to store new data. As a result, when I tried to print the list, I got an infinite loop. Can somebody tell me what's wrong here?
struct node
{
double value;
node * next_ptr;
node(){}
node(double val, node * p): value(val), next_ptr(p) {}
~node(){}
};
node * create()
{
using namespace std;
node temp = {0, nullptr};
node * result;
for(int i=1; i<5; ++i)
{
result = new node;
result->value = i;
result->next_ptr = &temp;
temp = *result;
}
return result;
};
The reason you are probably getting an infinite loop is because in:
temp = *result;
you are copying the value of *result into a new object of type node, which is unrelated to the one you created.
What you want to do is store a pointer instead:
node* temp = nullptr;
node* result;
for(int i=0; i<5; ++i)
{
result = new node;
result->value = i;
result->next_ptr = temp;
temp = result;
}
return result;
Live demo
A part from the learning value, just stick to std::forward_list or std::list, for lists, instead. Or even better just use std::vector or other containers (depending on the use that you make of the container).
a simple one to create linked in for loop
#include <iostream>
class LinkedList {
public:
int value;
LinkedList * next;
};
int main()
{
LinkedList *List = nullptr;
LinkedList *head = List;
LinkedList *prev;
for (int i=0; i< 3;i++)
{
LinkedList *temp = new(LinkedList);
temp->value = i;
temp->next = nullptr;
if (head == nullptr)
{
head = temp;
prev = head;
}
else
{
prev->next = temp;
prev = temp;
}
}
}

How to dynamically create new nodes in linked lists C++

Could anyone tell me if this is the basic idea of linked lists? What are the pros and cons to this method and what are best practices when implementing linked lists in C++? Im new to data structures so this is my first approach. If there is a better way to do this same thing, please let me know. Additionally, how would you create the nodes dynamically without hard coding it? Thanks.
#include <iostream>
#include <string>
using namespace std;
struct node {
int x;
node *next;
};
int main()
{
node *head;
node *traverser;
node *n = new node; // Create first node
node *t = new node; // create second node
head =n; //set head node as the first node in out list.
traverser = head; //we will first begin at the head node.
n->x = 12; //set date of first node.
n->next = t; // Create a link to the next node
t->x = 35; //define date of second node.
t->next = 0; //set pointer to null if this is the last node in the list.
if ( traverser != 0 ) { //Makes sure there is a place to start
while ( traverser->next != 0 ) {
cout<< traverser->x; //print out first data member
traverser = traverser->next; //move to next node
cout<< traverser->x; //print out second data member
}
}
traverser->next = new node; // Creates a node at the end of the list
traverser = traverser->next; // Points to that node
traverser->next = 0; // Prevents it from going any further
traverser->x = 42;
}
for tutorial purpose, you can work out this example:
#include <iostream>
using namespace std;
struct myList
{
int info;
myList* next;
};
int main()
{
//Creation part
myList *start, *ptr;
char ch = 'y';
int number;
start = new myList;
ptr = start;
while (ptr != NULL)
{
cout << "Enter no. ";
cin >> ptr->info;
cout << "Continue (y/n)? ";
cin >> ch;
if (ch == 'y')
{
ptr->next = new myList;
ptr = ptr->next;
}
else
{
ptr->next = NULL;
ptr = NULL;
}
}
//Traversal part begins
cout << "Let's start the list traversal!\n\n";
ptr = start;
while (ptr!=NULL)
{
cout << ptr->info << '\n';
ptr = ptr->next;
}
}
It allocates memory dynamically for as many elements as you want to add.
I'd prefer to make a linked list class. This eliminates the need to call 'new' more than once. A nice implementation with examples can be found here.
You are in fact already doing dynamic allocation. So, not sure what you are asking for. But if you want to define functions to add new nodes to your linked list (or delete a node etc.), this can be a probable solution:
The location nodes get inserted/deleted is dependent on the type of data-structure. In a queue, new nodes will get added to the end; at the top in case of a stack. A function that adds a node to the top, simulating STACK push operation:
void pushNode(node **head, int Value) {
node *newNode = new node;
newNode->x = Value;
newNode->next = *head;
*head = newNode;
}
It would be called like pushNode(&head, 15) where 'head' would be defined as node *head = NULL. The root head should initially be set to NULL. After this operation head will point to the newly added node (top of stack).
The approach would be very similar for other data-structures (viz. queues) and works fine. But as you are using C++, I would suggest to define a class for your linked-list and define these functions as methods. That way, it will be more convenient and less error-prone.
Even better use std::list. It's the standard thing, so much portable and robust than a custom implementation.
You can also do it in this way
#include <iostream>
using namespace std;
struct Node{
int data;
Node* next;
};
void createList(Node** head ,Node* temp){
int n;
char ch;
temp = *head;
while(temp != NULL){
cout<<"Enter The Value ";
cin>>temp->data;
cout<<"DO you want to continue(y/n)";
cin>>ch;
if(ch=='Y' || ch == 'y'){
temp->next = new Node;
temp = temp->next;
}else{
temp->next = NULL;
temp = NULL;
}
}
}
void ShowList(Node* head){
cout<<"your list :"<<endl;
while(head != NULL){
cout<<head->data<<" ";
head = head->next;
}
}
int main()
{
//Creation part
Node *head, *temp;
createList(&head,temp);
ShowList(head);
}

Create and Display Linked List

I am a beginner in C++ and need help in many things. Well, for the starters, I have been working on Linked List and not really getting why my header(the first pointer which points towards first node) keep on rotating. I am just pointing it towards first node plus my display node is just displaying last node, why is it so?. Please tell me where I am wrong. Thank you in advance
#include <iostream>
#include <conio.h>
using namespace std;
struct Node
{
int data;
Node *link;
};
Node* create_Node()
{
int no_of_nodes;
Node *header = new Node;
Node *ptr = new Node;
header = ptr;
cout << "Enter no of nodes:";
cin >> no_of_nodes;
cout << "Enter data:";
for(int n = 0; n < no_of_nodes; n++)
{
cin >> ptr->data;
Node *temp = new Node;
ptr->link = temp;
temp = ptr;
}
ptr->link = NULL;
return ptr;
}
void display_link_list(Node * list)
{
Node *temp = new Node;
temp = list;
while(temp != NULL)
{
if(temp->link != NULL)
{
cout << "List:" << list->data << endl;
temp = temp->link;
}
}
}
int main()
{
Node *n = new Node;
n = create_Node();
display_link_list(n);
getch();
return 0;
}
Welcome to C++. My advice here is to break the Linked list into two. First the Nodes and then a List struct.
struct Node
{
int data;
Node *next;
Node(int data) : data(data), next(NULL) {}
};
struct List {
Node* tail;
Node* head;
List() : head(NULL), tail(NULL) {}
void insert(int data) {
if(head==NULL) {
head = new Node(data);
tail = head;
} else {
tail->next = new Node(data);
tail = tail->next;
}
}
};
Now you can insert one element into the list at a time and use head to print the list from beginning to end.
Something basic that you need to understand:
When you do Node* p = new Node, you are setting variable p to point to the start address of a piece of memory, the size of which being equal to sizeof(Node).
Now, when you then do p = something else (which often appears in your code), you are essentially overriding the previous value of p with some other value. It is like doing:
int i = 5;
i = 6;
So your code does not do what you're expecting to begin with.
In addition to that, what's bad about overriding the first value with a second value in this case, is the fact that the first value is the address of a dynamically-allocated piece of memory, that you will need to delete at a later point in your program. And once you've used p to store a different value, you no longer "remember" that address, hence you cannot delete that piece of memory.
So you should start by fixing this problem in each of the following places:
Node *header = new Node; // Variable 'header' is assigned
header = ptr; // Variable 'header' is reassigned
Node *temp = new Node; // Variable 'temp' is assigned
temp = list; // Variable 'temp' is reassigned
Node *n = new Node; // Variable 'n' is assigned
n = create_Node(); // Variable 'n' is reassigned

C++ Linked list

I'm trying to make linked list similar too the one here:
linked list in C
That is to have the "head", I called it first, inside another struct. However I found doing that change. Makes it hard to add values to the list_item struct. I have tried some few things to see if it works. It compiles, however when I run the code it will crash. Any help would be helpful here. I know the cause of the crash is when I want to point the new_node to the linked_list.
#include <iostream>
using namespace std;
struct list_item
{
int key;
int value;
list_item *next;
};
struct list
{
struct list_item *first;
};
int main()
{
list *head;
list *new_node;
head = NULL;
head->first = NULL;
for(int i = 0; i < 10; i++)
{
//allocate memory for new_node
new_node = (list*)malloc(sizeof(list));
new_node->first = (list_item*)malloc(sizeof(list_item));
//adding the values
new_node->first->key = i;
new_node->first->value = 10 + i;
//point new_node to first;
new_node->first->next = head->first;
//point first to new_node;
head->first = new_node->first;
}
//print
list *travel;
travel->first = head->first;
int i = 0;
while(travel != NULL)
{
cout << travel->first->value << endl;
travel->first = travel->first->next;
}
return 0;
}
You are creating 10 lists, I think you might try to do something like this:
#include <iostream>
using namespace std;
struct list_item
{
int key;
int value;
list_item *next;
};
struct list
{
struct list_item *first;
};
int main()
{
//Just one head is needed, you can also create this
// on the stack just write:
//list head;
//head.first = NULL;
list *head = (list*)malloc(sizeof(list));
list_item *new_node = NULL;
head->first = NULL;
for(int i = 0; i < 10; i++)
{
//allocate memory for new_node
new_node = (list_item*)malloc(sizeof(list_item));
//adding the values
new_node->key = i;
new_node->value = 10 + i;
//if the list is empty, the element you are inserting
//doesn't have a next element
new_node->next = head->first;
//point first to new_node. This will result in a LIFO
//(Last in First out) behaviour. You can see that when you
//compile
head->first = new_node;
}
//print the list
list_item *travel;
travel = head->first;
while(travel != NULL)
{
cout << travel->value << endl;
travel = travel->next;
}
//here it doesn't matter, but in general you should also make
//sure to free the elements
return 0;
}
This is what is going on. At first you only have one head and no elements.
head
|
|
V
NULL
Then you add your first element. Make sure that the "new_node->next==NULL":
head
|
|
V
node: ------------------> NULL
key = 0
value = 10
Then you add another node in front but append your first node to its next node. you move the pointer from the head to the new node
head:
first
|
|
V
node: ---------> node: -------------> NULL
key: 1 key: 0
value: 11 value: 10
etc.
Since you are using c++, you might consider using "new" and "delete". Just replace
new_node = (list_item*)malloc(sizeof(list_item));
with
list *head = new list
The next line only allocates memory for your list struct. The list contains only a pointer, you must also allocate memory for new_node->first before assigning to any of its members.
//allocate memory for new_node
new_node = (list*)malloc(sizeof(list));
I think you want something more like this:
#include <iostream>
#include <cstdlib>
using namespace std;
typedef struct tag_list_item
{
int key;
int value;
struct tag_list_item *next;
} list_item;
typedef struct
{
list_item *head;
} list;
int main()
{
list my_list;
list_item *new_node;
list_item *previous_node = NULL;
my_list.head = NULL;
for(int i = 0; i < 10; i++)
{
//allocate memory for new_node
new_node = (list_item*)malloc(sizeof(list_item));
//adding the values
new_node->key = i;
new_node->value = 10 + i;
if(previous_node == NULL)
{
my_list.head = new_node;
}
else
{
previous_node->next = new_node;
}
previous_node = new_node;
}
//print
list_item *iter = my_list.head;
while(iter != NULL)
{
cout << iter->value << endl;
iter = iter->next;
}
return 0;
}
Changes of note:
For malloc, I added:
#include <cstdlib>
I changed your list structures to typedefs, had to declare "next" using the tag since the typedef isn't complete at that point
typedef struct tag_list_item
{
int key;
int value;
struct tag_list_item *next;
} list_item;
I changed your list name to "my_list" and declared it directly (without the pointer). In this case you can just have the compiler allocate it automatically on the stack.
list my_list;
I keep a pointer for "previous_node" so that you can assign the "next" pointer much more easily. Notice that the first node allocated is pointed to by the "head" pointer in the list structure. I believe that is the traditional name for the pointer to the first element in a list.
if(previous_node == NULL)
{
my_list.head = new_node;
}
else
{
previous_node->next = new_node;
}
previous_node = new_node;
head = NULL;
head->first = NULL;
There's the issue. You can't follow a pointer and set it to NULL if you've set the pointer itself to NULL.
That should be
head = malloc(sizeof(list));
head->first = NULL;
That should fix your code.
Hope that helps,
Billy3
EDIT: There's also an issue with your FOR loop. When you allocate the list, you should only allocate the list itself once. When you insert an item, you only allocate a list_item. You're assigning a list pointer to a member which accepts only a list_item pointer ;)
See Gabe's post for a demonstration of correct behavior :)
Look at your struct declaration
struct list_item
{
int key;
int value;
list_item *next;
};
That should be
struct list_item
{
int key;
int value;
struct list_item *next;
};
Hope this helps,
Best regards,
Tom

Categories