I've been learning Data Structures and currently working with Linked List. I'm trying to add a node at the end of the linked list but not able to figure out the correct logic for it. I've tried inserting a node at the beginning and it works fine.
This is the code:
#include <bits/stdc++.h>
using namespace std;
class Node {
public:
int data;
Node* next;
};
Node* head; // global
void Insert(int data) {
Node* temp = new Node();
temp -> data = data;
temp -> next = head;
head = temp;
} // insert an integer
void Print(){
Node* temp = head;
cout << "List is: ";
while (temp != NULL) {
cout << temp -> data << " ";
temp = temp -> next;
}
cout << endl;
} // print all elements in the list
void Delete(int n){
Node* temp1 = head;
if(n == 1) {
head = temp1 -> next; // head now points to second node
delete temp1;
return;
}
int i;
for(i = 0; i < n-2; i++)
temp1 = temp1 -> next;
// temp1 points to (n-1)th Node
Node* temp2 = temp1 -> next; // nth Node
temp1 -> next = temp2 -> next; // (n+1)th Node
delete temp2; // delete temp2
} // Delete node at position n
int main() {
head = NULL; // empty list
Insert(2);
Insert(4);
Insert(6);
Insert(5); // List: 2,4,6,5
Print();
int n;
cout << "Enter a postion: " << endl;
cin >> n;
Delete(n);
Print();
}
This code deletes a node at nth position. The node here is being adding from the beginning and I'm trying to figure out the logic to insert it from the end.
Any suggestions and advises on this will be very helpful.
Thanking you in advance.
Play with the code.
void insert_end(int data) {
Node* temp = new Node(); // 1
temp->data = data;
temp -> next = nullptr;
Node* n = head;
if (!n) { // 2
head = temp;
return;
}
while(n->next) { // 3
n = n->next;
}
n->next = temp;
}
Short explanation of the method:
1: You create a new Node and set the data.
2: Check if the list is empty. If it is, insert the new element at the head.
3: If the list is not empty, you read the next element of the list until you have the last Node in your list. If you would write while(n)... here, you would get to the end of the list, meaning a nullptr and the code would break.
Related
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;
}
I am trying to code for insertion and deletion in linked list.
Here is my code for basic insertion and deletion of nodes in a singly linked list.
There are no errors in the code, but the output on the terminal shows segmentation fault. Can someone explain why am I getting a segmentation fault? And what changes do i make to remove the fault.
I believe the segmentation fault is in the deletion part. Please help.
// class is a type of user defined datatype
class Node {
public:
int data;
Node* next;
//constructor
Node(int data) {
this -> data = data;
this -> next = NULL;
}
// destructor
~Node() {
int value = this -> data;
//memory free krr rhe hain
if(this -> next != NULL){
delete next;
this -> next = NULL;
}
cout << "memory is free for node with data" << value << endl;
}
};
void insertAtHead(Node* &head, int data) {
// creating new node called temp of type Node
Node* temp = new Node(data);
temp -> next = head;
head = temp;
}
void insertAtTail(Node* &head, Node* &tail, int data) {
// //New node create
// Node* temp = new Node(data);
// tail -> next = temp;
// tail = temp;
Node* temp = new Node(data);
if (head == nullptr) { // If this is the first node of the list
head = temp;
} else { // Only when there is already a tail node
tail -> next = temp;
}
tail = temp;
}
void insertAtPosition(Node* &tail, Node* &head, int position, int data) {
// Insert at starting
if(position == 1) {
insertAtHead(head, data);
return;
}
// Code for inserting in middle
Node* temp = head;
int cnt = 1;
while(cnt < position-1) {
temp = temp -> next;
cnt++;
}
// Creating a node for data
Node* nodeToInsert = new Node(data);
nodeToInsert -> next = temp -> next;
temp -> next = nodeToInsert;
// Inserting at last position (tail)
if(temp -> next == NULL) {
insertAtTail(head,tail, data);
return;
}
}
void deleteNode(int position, Node* &head) {
//deleting first or starting node
if(position == 1) {
Node* temp = head;
head = head -> next;
//memory free start node
temp -> next = NULL;
delete temp;
} else {
// deleting any middle node
Node* curr = head;
Node* prev = NULL;
int cnt = 1;
while(cnt <= position) {
prev = curr;
curr = curr -> next;
cnt++;
}
prev -> next = curr -> next;
curr -> next = NULL;
delete curr;
}
}
void print(Node* &head) {
Node* temp = head;
while(temp != NULL) {
cout << temp -> data << " ";
temp = temp -> next;
}
cout << endl;
}
int main() {
Node* head = nullptr; // A list has a head
Node* tail = head; // a tail.
insertAtHead(head, 10); // pass the head
insertAtTail(head, tail, 20);
insertAtTail(head, tail, 30);
insertAtHead(head, 5);
print(head); // Print the whole list
cout << "head" << head -> data << endl;
cout << "tail" << tail -> data << endl;
deleteNode(1, head);
print(head);
}
The problem is not with the delete function since even commenting it out leads to segmentation fault.
The problem is that you are initializing tail = head which is set to nullptr at the start. However, when you insertAtHead, you set the value of head but leave the tail to nullptr. You need to do tail = head when adding the first node (when head == nullptr).
Refer below for working code:
// Online C++ compiler to run C++ program online
#include <iostream>
using namespace std;
// class is a type of user defined datatype
class Node {
public:
int data;
Node* next;
//constructor
Node(int data) {
this -> data = data;
this -> next = NULL;
}
// destructor
~Node() {
int value = this -> data;
//memory free krr rhe hain
if(this -> next != NULL){
delete next;
this -> next = NULL;
}
cout << "memory is free for node with data" << value << endl;
}
};
void insertAtHead(Node* &head,Node* &tail, int data) {
// creating new node called temp of type Node
Node* temp = new Node(data);
temp -> next = head;
if (head == nullptr)
tail = temp; //inializing tail
head = temp;
}
void insertAtTail(Node* &head, Node* &tail, int data) {
// //New node create
// Node* temp = new Node(data);
// tail -> next = temp;
// tail = temp;
Node* temp = new Node(data);
if (head == nullptr) { // If this is the first node of the list
head = temp;
} else { // Only when there is already a tail node
tail -> next = temp;
}
tail = temp;
}
void insertAtPosition(Node* &tail, Node* &head, int position, int data) {
// Insert at starting
if(position == 1) {
insertAtHead(head,tail, data);
return;
}
// Code for inserting in middle
Node* temp = head;
int cnt = 1;
while(cnt < position-1) {
temp = temp -> next;
cnt++;
}
// Creating a node for data
Node* nodeToInsert = new Node(data);
nodeToInsert -> next = temp -> next;
temp -> next = nodeToInsert;
// Inserting at last position (tail)
if(temp -> next == NULL) {
insertAtTail(head,tail, data);
return;
}
}
void deleteNode(int position, Node* &head) {
//deleting first or starting node
if(position == 1) {
Node* temp = head;
head = head -> next;
//memory free start node
temp -> next = NULL;
delete temp;
} else {
// deleting any middle node
Node* curr = head;
Node* prev = NULL;
int cnt = 1;
while(cnt <= position) {
prev = curr;
curr = curr -> next;
cnt++;
}
prev -> next = curr -> next;
curr -> next = NULL;
delete curr;
}
}
void print(Node* &head) {
Node* temp = head;
while(temp != NULL) {
cout << temp -> data << " ";
temp = temp -> next;
}
cout << endl;
}
int main() {
Node* head = nullptr; // A list has a head
Node* tail = head; // a tail.
insertAtHead(head,tail, 10); // pass the head
insertAtTail(head, tail, 20);
insertAtTail(head, tail, 30);
insertAtHead(head,tail, 5);
print(head); // Print the whole list
cout << "head" << head -> data << endl;
cout << "tail" << tail -> data << endl;
deleteNode(1, head);
print(head);
}
The segfault is actually in the function insertAtTail(), and is because, while you handle the case where head is a null pointer, you do not handle the case where there is a head node but no tail node. The following code fixes this issue:
void insertAtTail(Node* &head, Node* &tail, int data) {
// //New node create
Node* temp = new Node(data);
if (head == nullptr) { // If this is the first node of the list
head = temp;
} else if (tail == nullptr) { // if there's a head but no tail
head -> next = temp;
} else { // Only when there is already a tail node
tail -> next = temp;
}
tail = temp;
}
If you have a look at this part of your code:
int main()
{
Node* head = nullptr; // A list has a head
Node* tail = head; // a tail.
insertAtHead(head, 10); // pass the head
insertAtTail(head, tail, 20);
return 0;
}
tail is a nullptr as you pass it into insertAtTail(head, tail, 20);
Then in insertAtTail you are going to access this nullptr:
void insertAtTail(Node* &head, Node* &tail, int data) {
// //New node create
// Node* temp = new Node(data);
// tail -> next = temp;
// tail = temp;
Node* temp = new Node(data);
if (head == nullptr) {
head = temp;
} else {
// here you have nullptr access resulting in your segmentation fault
tail -> next = temp;
}
tail = temp;
}
my program is for sorting a letters entered by the user and each letter is followed by its position to create a word using linked list " the word should be ended by -1 to stop insertion". my problem is when I enter the input nothing happen after that I think the problem is at the function printList(Node* head) put I cant get it .
include <iostream>
using namespace std;
/* Link list node */
class Node
{
public:
int data;
char x;
Node* next;
void sortedInsert(Node** head_ref, Node* new_node);
Node* newNode(int new_data);
void printList(Node* head);
~Node() {};
};
/* function to insert a new_node
in a list. Note that this
function expects a pointer to
head_ref as this can modify the
head of the input linked list
(similar to push())*/
void Node::sortedInsert(Node** head_ref, Node* new_node)
{
Node* a = new Node();
// Advance s to index p.
Node* current;
// Special case for the head end
if (*head_ref == NULL || (*head_ref)->data >= new_node->data)
{
new_node->next = *head_ref;
*head_ref = new_node;
}
else
{
// Locate the node before the point of insertion
current = *head_ref;
while (current->next != NULL && current->next->data < new_node->data)
{
current = current->next;
}
new_node->next = current->next;
current->next = new_node;
}
}
/* BELOW FUNCTIONS ARE JUST
UTILITY TO TEST sortedInsert */
/* A utility function to
create a new node */
Node* newNode(char x, int new_data)
{
/* allocate node */
Node* new_node = new Node();
/* put in the data */
new_node->data = x;
new_node->data = new_data;
new_node->next = NULL;
return new_node;
}
/* Function to print linked list */
void Node::printList(Node* head)
{
Node* temp = head;
Node* temp2 = head;
while (temp != NULL) {
cout << temp->data << temp2->data << " ";
temp = temp->next;
temp2 = temp2->next;
}
}
int main()
{
/* string s;
cout << " enter the letters to sort it : " << endl;
cin >> s;
sortString(s);
cout << endl;*/
long nums[1000];
char x[1000];
cout << " enter exprission followed by its positin to sort it 'enter -1 to end it' : ";
for (int i = 0; i < 1000; i++)
{
for (int j = 0; j < 1000; j++)
{
cin >> x[i] >> nums[j];
if (nums[j] == -1)
break;
Node* head = NULL;
Node* new_node = newNode(x[i], nums[j]);
sortedInsert(&head, new_node);
}
Node* head = NULL;
cout << "Created Linked List\n";
printList(head);
}
return 0;
}
There are a handful of (potential) bugs in your code. Here is the first one I found:
Node* newNode(char x, int new_data)
{
/* allocate node */
Node* new_node = new Node();
/* put in the data */
new_node->data = x; // OOPS, you probably mean new_node->x = x
new_node->data = new_data;
new_node->next = NULL;
return new_node;
}
I'm attempting to add items to the end of the list and remove them from the beginning of the list. The program compiles but crushes when I try to add items. I'm new to this concept an it's taking some time to settle in completely. Any help is appreciated..
Thanks!
#include<iostream>
using namespace std;
struct myNode
{
int val;
struct myNode *next;
};
class Cll
{
public:
myNode* head = new myNode;
myNode* tail = new myNode;
Cll()
{
head = NULL;
tail = NULL;
}
myNode* createAnode(int value)
{
myNode* temp;
temp = new myNode;
temp->val = value;
temp->next = NULL;
return temp;
}
void addingValues()
{
int numb;
cout<<"Enter the number to be added: ";
cin>>numb;
myNode *temp, *p;
temp = createAnode(numb);
p = head;
p = p-> next;
temp -> next = NULL ;
p -> next = temp;
}
void deletingValues()
{
myNode *s;
s = head;
head = s->next;
}
void showValues()
{
struct myNode *temp2;
temp2 = head;
while (temp2)
{
cout<<temp2->val<<"->";
temp2 = temp2->next;
}
cout<<"NULL"<<endl;
}
};
int main()
{
int pick ;
Cll cll;
int again;
do
{
cout<<"1.add"<<endl;
cout<<"2.delete"<<endl;
cout<<"3.show"<<endl;
cout<<"Enter choice : ";
cin>>pick;
switch(pick)
{
case 1:
cll.addingValues();
cout<<endl;
break;
case 2:
cll.deletingValues();
break;
case 3:
cll.showValues();
cout<<endl;
break;
}
cout << "Enter 1 to see again, enter 2 to quit"<< endl;
cin >> again;
} while (again == 1);
}
You are programming in c++, so I recommend to use std::list.
But if you like to do it yourself, and you like to ad a node at front of your single liked list, you first have to check if it is the first node or not.
If it is the first node your new node ist head and tail. If not the new node is the the head and its successor is the old head of the list. Adapt your code like this:
void addingValues()
{
int numb;
cout << "Enter the number to be added: ";
cin >> numb;
myNode *newNode = createAnode(numb);
if ( head == NULL ) // if list is empty the new node is the head and the tail
{
head = tail = newNode;
return;
}
tail->next = newNode; // successor of last node is new node and new node is tail
tail = newNode;
}
To delete a node from front of the list you have to check if the list is not empty and if it was the last node in the list:
void deletingValues()
{
if ( head == NULL )
return;
myNode *temp = head->next;
delete head;
head = temp;
if ( head == NULL )
tail == NULL;
}
I'm trying to implement Linked List on C++ by utilizing three separate functions:
Insert(int x, int n) - Takes the number to be inserted (x) and the position to be inserted at (n) starting with position 1.
Delete(int n) - Deletes the number at position (n) starting with position 1;
Print() - Prints the elements of the linked list.
Here is my code in C++:
#include<iostream>
#include<conio.h>
#include<stdlib.h>
using namespace std;
struct Node {
int data;
Node* next;
};
Node* head;
void Print()
{
cout << "The List is:" ;
Node* temp = head;
while (temp -> next != NULL)
{
temp = temp -> next;
cout << " " << temp -> data;
}
}
void Delete(int n)
{
if ( n == 1 )
{
Node* temp = head;
head = temp -> next;
delete temp;
return;
}
Node* temp1 = head;
for(int i = 0; i < n-2; i++)
{
temp1 = temp1 -> next;
}
Node* temp2 = temp1 -> next;
temp1 -> next = temp2 -> next;
delete temp2;
}
void Insert(int x, int n)
{
Node* temp = new Node();
temp -> data = x;
temp -> next = NULL;
if ( n == 1 )
{
temp -> next = head;
head = temp;
return;
}
Node* temp1 = head;
for (int i = 0; i < n-2; i++)
{
temp1 = temp1 -> next;
}
temp -> next = temp1 -> next;
temp1 -> next = temp;
}
int main()
{
head = NULL;
Insert(2,1);
Insert(3,1);
Insert(99,3);
Insert(4,2);
Insert(5,3); // 3, 4, 5, 99, 2
Print(); // 1st call
Delete(2);
Delete(3); // 3,5,2
Print(); // 2nd call
return 0;
}
The problem is that, according to my configuration, 1st call of the print function produces 4, 5, 2, 99 instead of 3, 4, 5, 2, 99. Also the second call shows 5, 99.
The problem is in your print function, try this:
void Print()
{
cout << "The List is:";
Node* temp = head;
while (temp != NULL)
{
cout << " " << temp->data;
temp = temp->next;
}
}
You need to print till temp itself is not NULL.
And in C++ I suggest using nullptr instead of NULL.
The two lines in the while loop, in the print function are inverted. You are moving your pointer to the next element and then printing, so you never print the first. Your function must look like this:
void Print()
{
cout << "The List is:" ;
Node* temp = head;
while (temp -> next != NULL)
{
cout << " " << temp -> data;
temp = temp -> next;
}
}