Inserting an element at the tail of linked list - c++

I am new to data structures. I finally got the hang of adding new element at the beginning of linked list
but now there is another problem. I have watched so many YouTube videos yet the problem isn't solved. I am trying to add an element at the end of this linked list but when I do the first two elements disappear. Please help!
#include <iostream>
using namespace std;
class Node{
public:
int data;
Node *next;
Node(){
data = 0;
next = NULL;
}
};
Node* add_end(Node* a, int new_data){
Node* ptr, *temp;
ptr = a;
temp = new Node();
temp->data = new_data;
temp->next = NULL;
while(ptr->next != NULL) {
ptr = ptr->next;
}
ptr->next = temp;
return ptr;
}
void print(Node* a){
while(a != NULL){
cout << a->data << " ";
a = a->next;
}
}
int main(){
Node *head = NULL;
Node *second = NULL;
Node *third = NULL;
head = new Node();
second = new Node();
third = new Node();
head->data = 1;
head->next = second;
second->data = 2;
second->next = third;
third->data = 3;
third->next = NULL;
cout << "Before Adding:\n";
print(head);
head = add_end(head, 4);
cout << "\nAfter Adding: \n";
print(head);
return 0;
}

The function add_end should return the pointer to the head node.
Your current implementation returns the pointer to the second last node, which is calculated in the process of adding element.
You should return a instead of ptr from the function add_end.
Also you should return temp before the loop when ptr is NULL, or NULL will be dereferenced and it may lead to runtime error.

Related

Linked list infinite loop c++

I've created two linked lists it's supposed to do a union and a merge. If I run the functions separately it does the task it's supposed to do merge or union. But when I try to output both simultaneously, the code infinitely keeps going. I don't know if it has to do with my null or the functions themselves.
#include <iostream>
using namespace std;
struct Node{
int num;
Node *next;
};
//
Node * unionLL (Node * LA, Node * LB)
{
if(LA == NULL)
{
return LB;
}
if(LB == NULL)
{
return LA;
}
Node *temp = NULL;//Creation of a node name temp as a place holder
if(LA != NULL) // if LA is less than LB
{
temp = LA;
temp->next = unionLL(LA->next, LB);
}
else if(LB != NULL)
{
temp = LB;
temp->next = unionLL(LA,LB->next);
}
return temp;
}
Node * mergeLL (Node * LA, Node * LB) // method
{
if(LA == NULL)
{
return LB;
}
if(LB == NULL)
{
return LA;
}
Node *temp = NULL;//Creation of a node name temp as a place holder
if(LA->num<=LB->num) // if LA is less than LB
{
temp = LA;
temp->next = mergeLL(LA->next, LB);
}
else if(LB->num<=LA->num)
{
temp = LB;
temp->next = mergeLL(LA,LB->next);
}
return temp;
}
int main()
{
// set 1
Node *head = new Node(); // Creation of node
Node *neighbor1 = new Node();
Node *neighbor2 = new Node();
Node *neighbor3 = new Node();
neighbor3->num=11;
neighbor2->num=8;
neighbor1->num=5;
head->num= 3; // head is leading node
head->next =neighbor1;
neighbor1->next = neighbor2;
neighbor2->next = neighbor3;
neighbor3->next = NULL;
// set 2
Node *head2 = new Node(); // Creation of node
Node *neighbor6 = new Node();
Node *neighbor7 = new Node();
Node *neighbor8 = new Node();
Node *neighbor9 = new Node();
Node *neighbor10 = new Node();
head2->num= 2; // head is leading node
neighbor6->num=6; // neighbor points to num which value is 6
neighbor7->num=8;
neighbor8->num=9;
neighbor9->num=22;
neighbor10->num=24;
head2->next =neighbor6; //link to next element
neighbor6->next = neighbor7;
neighbor7->next = neighbor8;
neighbor8->next = neighbor9;
neighbor9->next = neighbor10;
neighbor10->next = NULL;
Node *head3 = head;
Node *head4 = head2;
Node *Merge = mergeLL(head,head2);
cout<<"mergeLL(LA, LB) = ";
while(Merge != NULL)
{
cout<<Merge->num; cout<<" "; //end is no new line
Merge= Merge->next;
}
Node *unionLLL = unionLL(head3,head4);
cout<<"unionLLL(LA, LB) = ";
while(unionLLL != NULL)
{
cout<<unionLLL->num; cout<< " ";
unionLLL= unionLLL->next;
}
return 0;
}
You are modifying the original linked lists in your mergeLL and unionLL functions. This is done when you change ->next to point to a different Node then it originally did. It is making some circular loops where head points to head2 and that is why it never reaches the end. Your mergeLL and unionLL functions need to create new Node() inside there, so that the original lists stay intact. Just copying the head node as you do in main doesn't preserve the original linked list order.
I've created a helpful printList function, that you can see the addresses, which can help you debug/design the linked list you want.
void printList(Node *head, const char *name)
{
cout << name << ":";
while (head != NULL)
{
cout << " " << head->num << "(" << head << ")";
head = head->next;
}
cout << "\n";
}
int main {
...
printList(head, "head");
printList(head2, "head2");
Node *Merge = mergeLL(head, head2);
printList(Merge, "mergeLL(LA, LB)");
printList(head, "head");
printList(head2, "head2");
...
}
returns
head: 3(0x1817eb0) 5(0x1817ed0) 8(0x1817ef0) 11(0x1817f10)
head2: 2(0x1817f30) 6(0x1817f50) 8(0x1817f70) 9(0x1817f90) 22(0x1817fb0) 24(0x1817fd0)
mergeLL(LA, LB): 2(0x1817f30) 3(0x1817eb0) 5(0x1817ed0) 6(0x1817f50) 8(0x1817ef0) 8(0x1817f70) 9(0x1817f90) 11(0x1817f10) 22(0x1817fb0) 24(0x1817fd0)
head: 3(0x1817eb0) 5(0x1817ed0) 6(0x1817f50) 8(0x1817ef0) 8(0x1817f70) 9(0x1817f90) 11(0x1817f10) 22(0x1817fb0) 24(0x1817fd0)
head2: 2(0x1817f30) 3(0x1817eb0) 5(0x1817ed0) 6(0x1817f50) 8(0x1817ef0) 8(0x1817f70) 9(0x1817f90) 11(0x1817f10) 22(0x1817fb0) 24(0x1817fd0)

How Can I Create A Single function that can create multiple Linked Lists

as shown in the code , i have to use 2 similar functions for creating 2 linked lists . isn't there a way i can create as many lists as i want with just one function , i tried using struct Node **p and struct Node *p as a parameter to the function but the didn't work
can someone help me to create multiple linked lists using this same function
and i want to create a append function not a insert function which asks for position as well.
#include <iostream>
using namespace std;
struct Node
{
int data = 10 ;
struct Node *next;
} *first , *second , *third;
void Display(struct Node *p)
{
while (p)
{
cout<<p->data<<" ";
p = p->next ;
}
cout<<"\n";
}
void Append_1(int elem)
{
Node* t , *last;
t = new Node;
t->data = elem;
t->next = NULL;
if(first == 0)
first = last = t;
else
{
last->next = t;
last = t;
}
}
void Append_2(int elem)
{
Node* t , *last;
t = new Node;
t->data = elem;
t->next = NULL;
if(second == 0)
second = last = t;
else
{
last->next = t;
last = t;
}
}
//void SortMerge(struct Node *p , struct Node *q);
int main()
{
Append_1(3);
Append_1(7);
Display(first);
Append_2(10);
Append_2(14);
Append_2(21);
Display(second);
//SortMerge(first , second);
Display(third);
return 0;
}
You can create a class like here:
struct Node{
int data;
Node* next;
Node* previous;
};
class Graph{
public:
Graph(int = 0);
~Graph();
void display_left_right();
void display_right_left();
void append(int);
void append_at_pos(int,int);
void prepend(int);
int get_num_elt();
int get_data_at_pos(int);
private:
Node* head;
Node* tail;
int num_elt=0;
};
Graph::Graph(int first_data){
head = new Node;
head->next = NULL;
head->previous = NULL;
head->data = first_data;
tail = head;
num_elt++;
}
Graph::~Graph(){
Node* main_traverser = head;
while(main_traverser){
main_traverser = head->next;
delete head;
head = main_traverser;
}
std::cout <<"Graph deleted!" << std::endl;
}
void Graph::display_left_right(){
Node* traverser = head;
while(traverser != NULL){
std::cout << traverser->data << " ";
traverser = traverser->next;
}
std::cout << std::endl;
}
void Graph::display_right_left(){
Node* traverser = tail;
while(traverser != NULL){
std::cout << traverser->data << " ";
traverser = traverser->previous;
}
std::cout << std::endl;
}
void Graph::append(int new_data){
Node* add = new Node;
add->data = new_data;
add->next = NULL;
add->previous = tail;
tail->next = add;
tail = add;
num_elt++;
}
void Graph::append_at_pos(int pos, int new_data){
if(pos > num_elt+1 || pos<=0){std::cout << "Wrong position!" << std::endl; return;}
if(pos==1){
prepend(new_data);
return;
}
if(pos==num_elt+1){
append(new_data);
return;
}
Node* add = new Node;
Node* traverser = head;
add->data = new_data;
for(int i=0; i<pos-2; i++){
traverser = traverser->next;
}
add->next = traverser->next;
add->previous = traverser;
traverser->next->previous = add;
traverser->next = add;
}
void Graph::prepend(int new_data){
Node* add = new Node;
add->next = head;
add->previous = NULL;
add->data = new_data;
head->previous = add;
head = add;
num_elt++;
}
int Graph::get_num_elt(){
return num_elt;
}
int Graph::get_data_at_pos(int pos){
Node* traverser = head;
if(pos <=0 || pos> num_elt){std::cout << "Wrong position!" << std::endl; return 0;}
for(int i=0; i<pos-1; i++){
traverser = traverser->next;
}
return traverser->data;
}
main(){
Graph a(2);
a.append(3);
a.append(4);
a.prepend(1);
a.display_left_right();
a.append_at_pos(1,6);
a.display_left_right();
std::cout << "data at 1: " << a.get_data_at_pos(1) << std::endl;
}
When you say "create multiple linked lists," I think you mean creating nodes to a linked list, which you have 2 append functions. I think the reason you have these 2 functions is because you do not know where to start traversing your linked list. For this reason, I think in your main function you should declare the head of the linked list, a single node that is the start. Set it's data and next to null, and then pass the head value into a function so it can start traversing from the head. Here is a generic append function that adds a node on the end, where the parameters are a reference to the head node, and the value for the new node:
void append(Node ** head, int new_data)
{
Node * select_node = * head;
// select node is set to the head node, and will traverse until it is at the end
while (select_node -> next != NULL)
{
// select node is set to the next node until it is NULL (end of linked list)
select_node = select_node -> next;
}
// now that select node is the last node, we need to make it's next value a node
// and that node should be a new node (allocated in heap) with the value of the input value
//and the next value be NULL (because it's the end of the linked list)
Node * next_node = new Node();
next_node -> data = new_data;
next_node -> next = NULL;
select_node -> next = next_node;
}

How do I make my Linked List Print backwards in C++

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.

Doubly linked list seg faults

I am trying to display a doubly linked list backwards, but every time I try to run anything even remotely touching the "prev" pointer in the program I get a seg fault.
I've been trying to figure this out for about 4 hours now and I just can't seem to pin it down. I can't tell if the issue is coming from my print backwards function or from the actual prev pointers themselves.
#include <iostream>
#include "list.h"
LinkedList::LinkedList(){
head = NULL;
tail = NULL;
};
bool LinkedList::addAtBeginning(int val){
Node *upd8L = head; // This Node will update Last
Node *upd8 = head;; // This Node will update the previous pointers
Node *point = new Node(); // This Node will insert the new node at the beginning
point->data=val; // This sets the data in the new node
point->next=head; // This sets the next pointer to the same as head
head = point; // This sets the head to the new Node
while(upd8){
upd8 = upd8->next;
upd8->prev = upd8L;
upd8L=upd8L->next;
}
return true;
};
bool LinkedList::remove(int val){
Node *temp = head;
Node *trail = 0;
while(temp != NULL){
if(temp->data == val){
if(temp->next == head->next){
head = head->next;
}else{
trail->next = temp->next;
}
delete temp;
}
trail = temp;
temp = temp->next;
}
return true;
};
void LinkedList::printForward() const{
Node *temp;
temp = head;
while(temp){
cout << temp -> data << endl;
temp = temp->next;
}
};
void LinkedList::printBackward() const{
Node *temp = head;
while(temp){
temp = temp->next;
cout << temp->data << endl;
}
while(temp){
cout << temp->data;
cout << "Pop" << endl;
temp = temp-> prev;
}
};
If possible, I'd love an explanation as to what is bugging up my program rather than just a straight answer, I want to know what I'm doing wrong and why it's wrong.
Thank you!
edit
Here's list.h
#ifndef LIST_H
#define 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
The function printBackward() may cause a seg-fault in the last iteration of the loop. while(temp) means iterate till you get the element out of the list NULL. Then you assigning temp = temp->next where temp->next is NULL. Now when you are calling cout << temp->data << endl; you are trying to get data from NULL pointer. Try to change the order. First display the node data, then change the temp pointer. An example:
void LinkedList::printBackward() const{
Node *temp = head;
while(temp){
cout << temp->data << endl;
temp = temp->next;
}
What you are doing wrong is getting the data from a NULL pointer.
So, I figured it out after a ton of trial and error!
The biggest issue I was having that kept giving me segmentation errors was whenever I was removing elements of the list I was failing to update the "prev" part of the node, and as a result any time I tried to read the list backwards I was getting a seg error.
//put your implementation of LinkedList class here
#include <iostream>
#include "list.h"
LinkedList::LinkedList(){
head = NULL;
tail = NULL;
};
bool LinkedList::addAtBeginning(int val){
Node *point = new Node(); // This Node will insert the new node at the beginning
point->data=val; // This sets the data in the new node
point->next=head; // This sets the next pointer to the same as head
head = point; // This sets the head to the new Node
if(head->next != NULL){
Node *temp = head->next;
temp->prev = head;
}
return true;
};
bool LinkedList::remove(int val){
Node *temp = head->next;
Node *trail = head;
if(head->data ==val){
head = head->next;
head->prev = NULL;
delete trail;
}else{
while(temp != NULL){
if(temp->data == val){
if(temp->next != NULL){
trail->next = temp->next;
delete temp;
temp= temp->next;
temp->prev=trail;
}else{delete temp;
trail->next = NULL;
}
}
trail = temp;
temp = temp->next;
}
}
return true;
};
void LinkedList::printForward() const{
Node *temp;
temp = head;
while(temp){
cout << temp->data << endl;
temp = temp->next;
}
};
void LinkedList::printBackward() const{
Node *temp = head;
while(temp->next != NULL){
temp = temp->next;
}
while(temp->prev != NULL){
cout << temp->data << endl;
temp = temp->prev;
}
cout << head->data << endl;
};

Printing the singly linked list

I am a newbie to programming
Here I wrote a code for accepting and displaying the values using linked list.
However the code takes all the values but displays only the last value
Here is the code
#include <iostream>
using namespace std;
struct node {
int value;
node* next;
};
class llist {
public:
void create();
void display();
node* head = NULL;
};
void llist::create()
{
struct node* temp;
temp = NULL;
struct node* p;
p = new struct node;
cin >> p->value;
if (head == NULL) {
head = p;
}
else {
temp = head;
while (temp->next != NULL) {
temp = temp->next;
}
temp->value = p->value;
temp->next = NULL;
}
}
void llist::display()
{
struct node* temp = head;
while (temp != NULL) {
cout << "VALUE:" << temp->value << endl;
temp = temp->next;
}
}
int main()
{
int n, i;
llist l1;
cin >> n;
for (i = 0; i < n; i++)
l1.create();
cout << "Displaying list\n";
l1.display();
return 0;
}
Input:
4
1
2
3
4
Displaying list
VALUE:4
I am wondering what went wrong...
Change this:
else {
temp = head;
while (temp->next != NULL) {
temp = temp->next;
}
temp->value = p->value;
temp->next = NULL;
}
to this:
else {
temp = head;
while (temp->next != NULL) {
temp = temp->next;
}
temp->next = p;
}
When inserting a new element at the end of a linked list, you find the last element inside the while loop and put it in the temp variable. Then you assign its next value to your new p element. The way you were doing before, you were just overriding the integer number of the last element. That is why when you printed your list you only got the last number you entered.
Also, when creating a new element p, be sure to initialize its next value to NULL:
p = new struct node;
p->next = NULL;
Problem is with the last 2 lines in the else block.
You are overwriting the value and maintaining just the single mode in your list class. And that's the reason, only last value is displayed.
Replace
temp->value = p->value;
temp->next = NULL;
With
temp->next = p;