My insert method should have P as taking in the first value (0) and 15 being the last value of the link list. Though, when I print out my list, I have to go through p->succ instead of p-prev to print out the items, and it prints out 15, 14, 13....; is this right? or am i implementing my functions wrong?
class Node{
public:
int value;
Node *succ;
Node *prev;
Node(int val, Node *s=NULL, Node *p=NULL)
:value(val),succ(s),prev(p){}
Node *insert(Node *p,Node *n)
{
if(n==NULL)
return p;
if(p==NULL)
return n;
n->succ=p;
if(p->prev)
p->prev->succ=n;
n->prev=p->prev;
p->prev=n;
return n;
}
int main(int argc, char *argv[]) {
Node *p= NULL;
for(int i = 0; i<=15; i++){
p = insert(p, new Node(i));
}
while(p){
cout<<p->value;
head=p->succ;
}
You are adding your nodes at the beginning. So obviously the last one added will be the first. If you want the nodes in the order you added, you need to add the nodes at the end.
Node *insert(Node *p,Node *n)
{
Node * ptr;
if(n==NULL)
return p;
if(p==NULL)
return n;
ptr = p;
// Traverse to the end of the list
while(ptr->succ)
{
ptr = ptr->succ;
}
ptr->succ = n;
n->prev = ptr;
return p;
}
Related
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;
}```
I'm writing a piece of code to append a node to the end of a singly linked list, but it seems that it doesn't append anything at all. Can anybody give me some idea of what I'm doing wrong?
#include<iostream>
using namespace std;
struct Node{
int val;
Node* next;
Node(int v) : val(v), next(NULL) {}
};
void append(Node &head, int d){
Node n = head;
while(n.next != NULL){
n = *n.next;
}
Node end(d);
n.next = &end;
}
int main(){
Node head(0);
for(int i=1;i<5;i++){
append(head, i);
}
Node n = head;
while(n.next != NULL){ //print the linked list, result is 0
cout << n.val<<" ";
n = *n.next;
}
cout<<n.val<<endl;
return 0;
}
EDIT: I changed the append() method to append a dynamically-allocated node each time, but it still doesn't work.
void append(Node &head, int d){
Node n = head;
while(n.next != NULL){
n = *n.next;
}
Node* end = new Node(d);
n.next = end;
}
You append the local object Node end(d); to the end of the linked list. This object is destroyed upon exist from append and the last list element points to a non-existent object.
A few issues with this.
You make a copies in your append function here Node n = head; and here n = *n.next. You then then finally make a change to the copy rather than the original.
You are assigning Node end(d) on the stack. When append returns it goes out of scope and is deleted.
You can fix both with,
#include<iostream>
#include <memory>
using namespace std;
struct Node{
int val;
std::shared_ptr<Node> next;
Node(int v) : val(v), next(nullptr) {}
};
void append(Node &head, int d){
Node* n = &head;
while(n->next != nullptr){
n = n->next.get();
}
n->next = std::make_shared<Node>(d);
}
int main(){
Node head(0);
for(int i=1;i<5;i++){
append(head, i);
}
Node n = head;
while(n.next != nullptr){
cout << n.val<<" ";
n = *n.next;
}
cout<<n.val<<endl;
return 0;
}
For the edited Question:
You are copying the head to n, then modify n. At the end of your append function, n is destroyed, but head was never touched.
This is how the list is laid out:
struct Node {
Node *next;
Node *prev;
T datum;
};
Node *first; // points to first Node in list, or 0 if list is empty
Node *last; // points to last Node in list, or 0 if list is empty
I have tried:
int i =0;
while(first->next)
{
i++;
}
but this does not seem right.
You can solve this by walking a pointer from node to node until the pointer is NULL. Count the number of times the pointer is non-NULL. The code required is very simple:
int list_size(const Node *ptr)
{
int size = 0;
while (ptr) {
size++;
ptr = ptr->next;
}
return size;
}
Use it like so:
int size = list_size(first);
This code doesn't use the prev pointer so it would also work for a singly-linked list.
your function needs to loop over the list while updating the pointer to the current node. Something like this :
function getLen(head) {
var curNode = head;
var len = 0;
while (curNode)
len++;
curNode = curNode.next;
}
return len;
}
Try this.
int i=0;
if(first!=0){
++i;
while(first!=last){
first=first->next;
++i;
}
}
std::cout<<i<<std::endl;
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;
}
}
}
I am trying to insert a value at the end of a doubly linked list , I get successful in inserting the value at head or first node but the second value is not getting inserted
The issue here is while entering the second value
class d_list
{
private:
struct node
{
double data;
node *next;
node *previous;
};
node *first;
node *last ;
public:
d_list(void)
{
first = nullptr;
last = nullptr;
};
void append(double);
};
void d_list::append(double num)
{
node *ptr;
node *toinsert;
if(!first)
{
first = new node;
first->previous= nullptr;
first->data = num;
last= new node;
first->next= last->previous;
last->previous = first->next;
last->next= nullptr;
}
else
{
if(last->next == nullptr)
{
ptr = new node;
ptr->next =last->previous;
ptr->data=num;
last->previous = ptr->next ;
}
last->next= nullptr;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
d_list aa;
cout<<"going to append first"<<endl;
aa.append(44);
cout<<"going to append second"<<endl;
aa.append(50.5);
return 0;
}
You have a number of problems in your code:
Your node next and previous members are never initialized anywhere and as a result are undefined when used. Either add a constructor to node or ensure they are initialized after allocation.
The addition of a node to an empty list is not correct. first->next is left undefined and why are you creating two nodes, both first and last? In a list with one element then first == last. The setting of next/previous in first/last doesn't make any sense either.
In a well formed double-linked list then last->next should always be null, as should first->previous.
The addition of a node into a non-empty list is also incorrect.
While you don't show it in the example, you'll eventually need a destructor as well as a copy operator and copy constructor (the rule of three). At the moment you are leaking memory and if you try to delete nodes you'll likely result in a double-free and crash.
I would suggest taking a step back from the code for a bit to ensure you properly understand the concepts behind a doubly-linked list. Draw out a list on paper with next/prev arrows and see how they need to be changed when adding nodes to an empty/non-empty list as well as how to delete and move nodes around. Once you figure out how next/prev should be set then translating that into code should be relatively straight forward.
Edit to answer comment:
To add a new node you can technically add it anywhere but it is usually added at the end (at least from what I've seen). See the other answers for a complete and correct code for adding new nodes in an empty and non-empty list.
...
if(last->next == nullptr)
{
ptr = new node;
ptr->next =last->previous; // <- is not correct
ptr->data=num;
last->previous = ptr->next ; // <- does not do anything useful
...
You don't append your new node to the list.
...
if(!last->next)
{
ptr = new node;
ptr->previous=last->previous;
ptr->next =last;
ptr->data=num;
last->previous = ptr ;
...
should be better. By the way: delete the allocated memory in a destructor!
I would write your double linked list in following code:
#include <iostream>
using namespace std;
class d_list
{
private:
struct node
{
double data;
node *next;
node *previous;
};
node *first;
// node *last ; no need for bidirectional list
public:
d_list(void)
{
first = nullptr;
//last = nullptr;
};
void append(double);
};
void d_list::append(double num)
{
node *ptr = new node;
ptr->data = num;
node *toinsert;
if(!first)
{
first = ptr;
first->previous=first->next=first;
}
else
{
if(first->next == first)
{
ptr->next = ptr->previous = first;
first->next = first->previous = ptr;
}
else{
node *last = first->previous;
ptr->next = first;
ptr->previous = last;
last->next = ptr;
first->previous = ptr;
}
}
}
int _tmain(int argc, _TCHAR* argv[])
{
d_list aa;
cout<<"going to append first"<<endl;
aa.append(44);
cout<<"going to append second"<<endl;
aa.append(50.5);
return 0;
}
Why have you inserted the declarations node *ptr; and node *toinsert; if you don't use them? Also it should be obvious that if you insert a single node at the end, then only one new element should be created(and you call new twice if first is null).
Try this code...
class d_list
{
private:
struct node
{
double data;
node *next;
node *previous;
};
node *first;
node *last ;
public:
d_list(void)
{
first = nullptr;
last = nullptr;
};
void append(double);
};
void d_list::append(double num)
{
node *ptr;
node *toinsert;
if(!first)
{
first = last = new node;
first->previous= nullptr;
first->next = nullptr;
first->data = num;
}
else
{
ptr = new node;
ptr->next =last->previous;
ptr->data=num;
last->previous = ptr->next ;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
d_list aa;
cout<<"going to append first"<<endl;
aa.append(44);
cout<<"going to append second"<<endl;
aa.append(50.5);
return 0;
}