Cycle remove from linklist gives segmentfault - c++

void removeLoop(Node* head)
{
// code here
// just remove the loop without losing any nodes
Node* rab=head;
Node* tur=head;
while(rab && rab->next)
{
rab=rab->next->next;
tur=tur->next;
if(tur==rab)
break;
}
Node* temp=NULL;
if(rab && rab->next)
{
rab=head;
while(rab!=tur)
{
rab=rab->next;
temp=tur;
tur=tur->next;
}
temp->next=NULL;
}
}
This is my code implemented using floyd algo.
Question link
https://practice.geeksforgeeks.org/problems/remove-loop-in-linked-list/1#
It is giving segment fault on submission not able to identify the particular test case it's failing
According to question no need to return anything.

If we take the input as
4
1 2 3 4
1
then it will show the segmentation error.
Reason: If you run the code on this specific testcase, then after running the first while loop, both tur and rab will point to the head of the list. Now the condition of while loop inside the if loop will always return false. And after that, the code on the next line temp->next=NULL will give error because temp was initially NULL and this line will exhibit undefined behavior.
The correct program should be:
void removeLoop(Node* head)
{
Node* rab=head;
Node* tur=head;
while (rab && rab->next) {
rab = rab->next->next;
tur = tur->next;
if (rab == tur)
break;
}
if (tur == rab)
{
tur = head;
if(tur == rab) {
while(rab->next != tur) rab = rab->next;
}
else {
while (tur->next != rab->next) {
rab = rab->next;
tur = tur->next;
}
}
rab->next = NULL;
}
}

Related

How these 2 algorithms' outputs are different from each other in a linked list data structure

I have created a Linked-List data structure as follows:
class Node<T> {
T value;
Node<T>? nextNode;
Node({required this.value, this.nextNode});
#override
String toString() {
if (nextNode == null) return '$value';
return '$value --> ${nextNode.toString()}';
}
}
Then create a LinkedList class that holds a head and tail node, and by printing the head, we can see the list of values.
class LinkedList<E> {
Node<E>? head;
Node<E>? tail;
bool get isEmpty => head == null;
// To add a node in front of the list
void push(E value) {
if (isEmpty) {
head = Node(value: value);
tail = head;
return;
}
head = Node(value: value, nextNode: head);
}
// To add a node behind the list
void append(E value) {
if (isEmpty) {
push(value);
return;
}
tail!.nextNode = Node(value: value);
tail = tail!.nextNode; //* variation 1
// tail = Node(value: value); //** variation 2
}
#override
String toString() {
return head.toString();
}
}
As you can see in the comments we could create 2 variations of the append algorithm.
The first one has tail = tail!.nextNode; and the second one has tail = Node(value: value); line.
The first variation works as we expected which means when we print the list it prints correctly as you can see here:
void main() {
final list = LinkedList<int>();
print(list); // output: 'Empty List'
list.append(1);
list.append(2);
list.append(3);
list.append(4);
print(list); // output : 1 --> 2 --> 3 --> 4
}
But with the second variation algorithm we have :
void main() {
final list = LinkedList<int>();
print(list); // output: 'Empty List'
list.append(1);
list.append(2);
list.append(3);
list.append(4);
print(list); // output : 1 --> 2
}
Why is the output different for the second algorithm?
Let's discuss the second algorithm step by step using your example.
list.append(1): Since the list is empty, a new head node is created.
list.append(2): A new node is created (let's say N2).
tail!.nextNode = Node(value: value); means that head.next points to N2.
However, when you do tail = Node(value: value), tail now points to an entirely new node, whereas head.next still points to N2.
list.append(3): Subsequent append calls will not add any new nodes to the original linked list, since the tail pointer is pointing to a arbitrary node which isn't connected to the original list.

c++ linked list, removing element disconnects the rest of the list

I was trying to implement this simple linked list project for my homework. When I tried to implement the removeByKey function, I ran into the problem that it disconnects the rest of the list entirely when it finds the key to be removed.
Here's the class:
class LancElem
{
private:
int key;
LancElem* next;
public:
LancElem(){next = nullptr;}
LancElem(int keyy, LancElem* nextt){key = keyy;next = nextt;}
LancElem* getNext(){return next;}
int getKey(){return key;}
void setNext(LancElem* nextt){next = nextt; }
void setKey(int keyy){key = keyy;}
};
The remove fucntion:
void removeByKey(LancElem& head, int key){
LancElem* n = head.getNext();
while(n->getNext()!=nullptr){
if(n->getNext()->getKey()==key){
n->setNext(n->getNext()->getNext());
delete n->getNext();
break;
}
n=n->getNext();
}
}
When I try to remove the biggest element:
The original linked list: 4 1 9 8 2 7 3 6 3
Expected output: 4 1 8 2 7 3 6 3
The real output: 4 1 0
The problem is probably where I connect the current element to the next->next element but I can't figure out why my implementation isn't good.
Ask yourself:
What is n->next after the line n->setNext(n->getNext()->getNext()); ? What does the line delete n->getNext(); delete?
You don't want to delete the just updated next but you want to delete the to be removed element:
auto to_be_deleted = n->getNext();
n->setNext(to_be_deleted->getNext());
delete to_be_deleted;
It seems your list has a dummy head node that does not have a value.
The function removeByKey can invoke undefined behavior when head.getNext() returns a null pointer due to using the expression n->getNext()
LancElem* n = head.getNext();
while(n->getNext()!=nullptr){
Also within the if statement
if(n->getNext()->getKey()==key){
n->setNext(n->getNext()->getNext());
delete n->getNext();
break;
}
you are trying to delete a node after the node to be deleted due to preceding assignment of the data member next by using the function setNext.
n->setNext(n->getNext()->getNext());
delete n->getNext();
Pay attention to that your function is unable to delete the node after the dummy head node due to using by you two times the call of getNext()
LancElem* n = head.getNext(); // the first call of getNext
while(n->getNext()!=nullptr){
if(n->getNext()->getKey()==key){ // the second call of getNext.
//...
The function can be defined like
void removeByKey( LancElem &head, int key )
{
if ( head.getNext() != nullptr )
{
if ( head.getNext()->getKey() == key )
{
LancElem *current = head.getNext();
head.setNext( head.getNext()->getNext() );
delete current;
}
else
{
LancElem *n = head.getNext();
while( n->getNext() != nullptr && n->getNext()->getKey() != key )
{
n = n->getNext();
}
if ( n->getNext() != nullptr )
{
LancElem *current = n->getNext();
n->setNext( n->getNext()->getNext() );
delete current;
}
}
}
}
Now try to use this function to delete the first node with the value 4 of your list and the function you currently have and compare their results.

Remove Duplicates from sorted list not passing all testcases

This is a question on leetcode. For some reason my code only works for 7/164 test cases. i would like to know why my algorithm is not efficient.
what is a solution to this? what is wrong with my code?
here is link to the problem
https://leetcode.com/problems/remove-duplicates-from-sorted-list/description/
edit: i have taken suggestions and edited code but my algorithm is still not passing, i am getting a time limit exceed error. is the algorithm efficient?
class Solution {
public:
ListNode* deleteDuplicates(ListNode* head) {
ListNode* current = head;
ListNode* nex;
while(current!=NULL){
nex=current->next;
if (nex==NULL)
break;
if(current->val==nex->val)
current->next=nex->next;
if (current->next==NULL)
break;
current==current->next;
if(current->next==NULL)
break;
}
return current;
}
};
nex is not initialized. You try to compare it with NULL before it is initialized.
You remove duplicates of the neighbor pairs only. It is OK for sorted lists.
You get into memory leaks.
The final two if are odd.
I think you return from the function not what is expected.
Used == where = should be used.
Your should not change current after current->next changed.
while (current && (nex = current->next)){
if (current->val == nex->val) {
current->next = nex->next;
delete nex;
} else {
current = current->next;
}
}
return head;
Remove Duplicates from Sorted List (JavaScript) -> try this one
let deleteDuplicates = (head) => {
let inArray = []
let check = head.reduce((a, c) => {
if(a[c]) a[c] = ++a[c];
else a[c] = 1;
return a
},{})
for (var i in check) {
if (check[i] == 1) inArray.push(Number(i))
}
return inArray;
}
let output = deleteDuplicates([3,7,4,4,2])
console.log(output)

C++ Recursion - adding tree data to list in order

My code is below - I'm trying to return to my main a list of aircrafts that I'm getting from a binary tree in order (smallesty to largest). For the code below, I get the root node twice. I've been working on it for hours... any suggestions?
Thanks,
Charlotte
std::list<Aircraft> Tree::buildList()
{
std::list<Aircraft> aircraftList;
if (_root != 0)
{
aircraftList = buildListHelp(_root, aircraftList);
aircraftList.push_front(*_root->getAircraftData());
}
return aircraftList;
}
std::list<Aircraft> Tree::buildListHelp(Node* node, std::list<Aircraft> aircraftList)
{
//aircraftList.push_back(*node->getAircraftData())
/*if (node->getLeft() != 0)
{*/
if (node==0)
return aircraftList;
buildListHelp(node->getLeft(), aircraftList);
//}
aircraftList.push_back(*node->getAircraftData());
/*if (node->getRight() != 0)
{*/
buildListHelp(node->getRight(), aircraftList);
//}
return aircraftList;
}
Assuming _root is declared as
Node* _root;
You are pushing it twice:
aircraftList.push_front(*_root->getAircraftData());
aircraftList.push_back(*node->getAircraftData());
In first call of buildListHelp

C++ Linked List Search Error: STATUS_ACCESS_VIOLATION

I am writing a program that adds, deletes, and displays nodes (that are doubly linked) and their components, but whenever I try to retrieve a node and display it's components I get this error:
2 [main] a 4640 exception::handle: Exception: STATUS_ACCESS_VIOLATION
2875 [main] a 4640 open_stackdumpfile: Dumping stack trace to a.exe.stackdump
I have narrowed it down to the search function within my .h file that is supposed to search to see if there is a node within the linked list that account number being searched. The function returns the node that comes before it, or the "previous" node.
Here is my search function:
bool searchListByAcctNum (int searchKey, nodePtr *prevOut)
{
bool found = false;
nodePtr p = headNum;
nodePtr prev = NULL;
while (p != NULL)
{
if (p->acctNum < searchKey)
{
prev = p;
p = p->nextNum;
}
else
{
if (p->acctNum == searchKey)
found = true;
p = NULL;
}
}
*prevOut = prev;
return found;
If anyone could help me at all, I'd appreciate it!
It looks like your list may be corrupted, or the pointer you're passing to receive the previous node is invalid, since that code looks okay. However, it seems to me that it could be written in a much simpler manner:
bool searchListByAcctNum (int searchKey, nodePtr *prevOut) {
/// Start at beginning of list, use pointer variable to hold previous.
nodePtr p = headNum;
*prevOut = = NULL;
// Process entire list, will exit early if need be.
while (p != NULL) {
// If past it, just return false, caller should ignore prevOut.
if (p->acctNum > searchKey)
return false;
// If equal, return true, prevOut holds previous or NULL if found at start.
if (p->acctNum == searchKey) {
return true;
// Save previous and advance to next.
*prevOut = p;
p = p->next;
}
// Reached end of list without finding, caller should ignore prevOut.
return false;
}