I am facing a problem while coding Linked List implementation in c++. Whenever I am trying to add an element he following code doesn't show any output. What's wrong with the code
#include<iostream>
using namespace std;
struct Node {
int data;
struct Node* ptr;
Node(int val) {
data = val;
ptr = NULL;
}
};
void addItem(struct Node* head, int val) {
struct Node* n = new Node(val);
if(head == NULL){
head = n;
return;
}
struct Node* cur = head;
while(cur->ptr != NULL){
cur = cur->ptr;
}
cur->ptr = n;
}
void printList(struct Node* head) {
struct Node* cur = head;
while(cur != NULL) {
cout << cur->data << " ";
cur = cur->ptr;
}
}
int main() {
struct Node* head = NULL;
addItem(head, 1);
addItem(head, 2);
addItem(head, 3);
addItem(head, 4);
printList(head);
return 0;
}
When I run the program it shows nothing on the terminal.
Output:
[Running] cd "c:\Users\Sonu\" && g++ LinkedList.cpp -o LinkedList && "c:\Users\Sonu\"LinkedList
[Done] exited with code=0 in 3.436 seconds
You should pass head by double pointer or by reference. Otherwise it will be just a copy on function argument which will get destroyed when coming out of the function.
void addItem(Node** head, int val) {
Node* n = new Node(val);
if(*head == NULL){
*head = n;
return;
}
Node* cur = *head;
while(cur->ptr != NULL){
cur = cur->ptr;
}
cur->ptr = n;
}
// ...
addItem(&head, 1); // take the address with &
or
void addItem(Node*& head, int val) {
Node* n = new Node(val);
if(head == NULL){
head = n;
return;
}
Node* cur = head;
while(cur->ptr != NULL){
cur = cur->ptr;
}
cur->ptr = n;
}
// ...
addItem(head, 1); // no change needed
Related
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);
}
I wrote the following code to reverse a linked list recursively for my homework. However, It's not connecting the links properly. Can please someone tell me what's wrong in the following reverse function? I have tried GDB as well. But, could not figure out what's wrong?
#include <iostream>
using namespace std;
class Node
{
public:
int data;
Node *next;
explicit Node(int data)
{
this->data = data;
next = nullptr;
}
};
void pushBack(Node * &head, Node * &tail, int data)
{
if(head == nullptr)
{
head = new Node(data);
tail = head;
}
else
{
tail->next = new Node(data);
tail = tail->next;
}
}
void printList(Node *head)
{
if(head == nullptr)
return;
cout << head->data << " ";
printList(head->next);
}
void reverseListRecursive(Node * &head)
{
if(head->next == nullptr)
{
return;
}
reverseListRecursive(head->next);
head->next->next = head;
head->next = nullptr;
}
int main()
{
int cap;
cin >> cap;
Node *head = nullptr, *tail = nullptr;
for(int i = 0; i < cap; ++i)
{
int element;
cin >> element;
pushBack(head, tail, element);
}
reverseListRecursive(head);
printList(head);
return 0;
}
Head is being passed by reference and also the infinite recursion is also not there.
The problem is that the head pointer needs to point to the last node of the linked list. Following code fixes the problem.
void reverseListRecursive(Node * &head, Node *temp = nullptr)
{
if(temp == nullptr)
temp = head;
if(temp->next == nullptr)
{
head = temp;
return;
}
reverseListRecursive(head, temp->next);
temp->next->next = temp;
temp->next = nullptr;
}
The below code is for merge sorting a linked list. Its giving out a segmentation fault. I really dont know how to deal with the above. All I could find was that I was trying to access a restricted part of the memory, the only place I think i could've gone wrong is re combining the two linked lists after splitting and sorting them under the split function body. I'd appreciate if I could get some guidance on how to deal with segmentation faults from here on & how to rectify them.
//Segmentation fault
#include <iostream>
using namespace std;
class Node
{
public:
int data;
Node *next;
Node(int data)
{
this->data = data;
next = NULL;
}
};
void print(Node *head)
{
Node *temp = head;
while (temp != NULL)
{
cout << temp->data << " ";
temp = temp->next;
}
}
Node *insert()
{
int data;
cin >> data;
Node *head = NULL;
Node *tail = NULL;
while (data != -1)
{
Node *n = new Node(data);
if (head == NULL)
{
head = n;
tail = n;
}
else
{
tail->next = n;
tail = tail->next;
}
cin >> data;
}
return head;
}
Node *sortedMerge(Node *h1, Node *h2)
{
// Node *fHead = NULL;
// Node *fTail = NULL;
if (!h1)
{
return h2;
}
if (!h2)
{
return h1;
}
if (h1->data < h2->data)
{
h1->next = sortedMerge(h1->next, h2);
return h1;
}
else
{
h2->next = sortedMerge(h1, h2->next);
return h2;
}
}
void split(Node *head, Node *h1, Node *h2)
{
Node *slow = head;
Node *fast = head->next;
while (fast != NULL)
{
fast = fast->next;
if (fast != NULL)
{
slow = slow->next;
fast = fast->next;
}
}
h1 = head;
h2 = slow->next;
slow->next = NULL;
}
void mergeSort_LL(Node *head)
{
Node *temp = head;
Node *h1;
Node *h2;
if ((temp == NULL) || (temp->next == NULL))
{
return;
}
split(temp, h1, h2);
mergeSort_LL(h1);
mergeSort_LL(h2);
head = sortedMerge(h1, h2);
}
int main()
{
Node *head = insert();
print(head);
cout << endl;
mergeSort_LL(head);
cout << "Sorted List is : " << endl;
print(head);
return 0;
}
Your call to split will not make h1 or h2 get a value. Arguments are passed by value. Since you evidently need h1 and h2 to get a different value from that split call, you should pass their addresses:
split(temp, &h1, &h2)
The function itself should therefore accept these addresses instead of the node pointers themselves:
void split(Node *head, Node **h1, Node **h2) {
// ...
*h1 = head;
*h2 = slow->next;
// ...
}
I am implementing a linked list with a merge sort function for a class project. My program compiles, but when I try to run it I get segmentation fault(core dumped). I debugged my program using GDB, and found that the segfault happens with the pointer frontRef and backRef in my listSplit() function (line 98 in the code below).
Can someone please help me? For the life of me I can't figure out why I am getting a segfault. I would greatly appreciate help with this.
#include "orderedList.h"
orderedList::orderedList() {
listLength = 0;
traversalCount = 0;
head = nullptr;
tail = nullptr;
}
void orderedList::add(int n) {
listLength++;
struct node* point = new node;
point->value = n;
point->next = nullptr;
if (head == nullptr) {
head = point;
tail = point;
}
else {
point->next = head;
head = point;
}
}
void orderedList::merge(struct node** headRef) {
struct node *listHead = *headRef;
struct node *a;
struct node *b;
if ((listHead == nullptr) || (listHead->next == nullptr)) {
return;
}
listSplit(listHead, &a, &b);
merge(&a);
merge(&b);
*headRef = sortedMerge(a, b);
}
orderedList::node* orderedList::sortedMerge(struct node* a, struct node *b)
{
struct node* result = nullptr;
if (a == nullptr) {
return (b);
}
if (b == nullptr) {
return (a);
}
if (a->value <= b->value) {
result = a;
result->next = sortedMerge(a->next, b);
}
else {
result = b;
result->next = sortedMerge(a, b->next);
}
return (result);
}
void orderedList::print() {
struct node* temp = head;
while (temp != nullptr) {
std::cout << temp->value << " ";
temp = temp->next;
}
delete(temp);
}
int orderedList::search(int key) {
int traversals = 1;
struct node* current = head;
struct node* previous = nullptr;
while (current != nullptr) {
if (current->value == key) {
if (previous != nullptr) {
previous->next = current->next;
current->next = head;
head = current;
return traversals;
}
}
previous = current;
current = current->next;
traversals ++;
}
return 1;
}
void orderedList::listSplit(struct node* source, struct node** frontRef, struct node** backRef) { // <--- Line 98
struct node* current = source;
int hopCount = ((listLength - 1) / 2);
for (int i = 0; i < hopCount; i++) {
current = current->next;
}
*frontRef = source;
*backRef = current->next;
current->next = nullptr;
}
You made *backRef point to current->next and then you let current->next = nullptr. This makes *backRef pointing to a nullptr. Did you later try to do something with the returned backRef, aka a node variable in your caller code?
#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.