typedef struct _node *Node;
typedef struct _list *List;
typedef struct _list {
Node head;
} list;
typedef struct _node {
int value;
Node next;
} node;
int listDeleteLargest(List l) {
Node meme = l->head;
int largest = meme->value;
while (meme != NULL) {
if (largest < meme->value) {
largest = meme->value;
}
meme = meme->next;
}
Node prev = l->head;
Node temp = prev->next;
Node current = prev->next;
while (current != NULL) {
if (prev->value == largest) {
temp = prev;
prev = prev->next;
l->head = prev;
free(temp);
} else if (current->value == largest) {
if (current->next == NULL) {
prev->next = NULL;
temp = current;
free(temp);
} else {
prev->next = current->next;
current = current->next;
temp = current;
free(temp);
}
}
current = current->next; //runtime error here
}
return 0;
}
//the struct typedef here.
For this code, I'm trying to delete the largest. The logic seems right but i keep getting a runtime error during current = current->next;
For example, if there are two large numbers in the linked list, it'll delete both. I wrote the code on the account that it caters for if the node is at the end, the end and the rest. I've run my tests but I still can't see why it wont compile properly.
If current->value != largest, you end up doing current = current->next twice, and risk running off the end of the list.
Also, this code:
temp = current;
free(temp);
will delete current, because both temp and current will be pointing at the same thing.
Related
I want to reverse a linked list in pair such that if the list is 1->2->3->4->X
then it should output the following 2->1->4->3->X
I have tried to solve this problem but it doesn't seem to run. Guys, can you please help me with what is wrong in my code.
ListNode* reverseListInPairs(ListNode *head){
ListNode *current = head,*newHead = NULL,*temp = NULL,*prev = NULL;
while(current != NULL && current->next != NULL){
temp = current->next;
current->next = current->next->next;
temp->next = current;
prev->next = temp;
prev = current;
current = current->next;
if(newHead == NULL){
newHead = temp;
}
}
return newHead;
}
what is wrong in my code.
The main problem I see is here:
prev->next = temp;
On the first iteration of the loop, prev is still NULL at that point, so you're performing a null-pointer dereference.
You can resolve that issue and also remove the special case for the list head by introducing a synthetic head node in front of the real nodes:
ListNode* reverseListInPairs(ListNode *head) {
ListNode fake_head = { .next = head };
ListNode *prev = &fake_head;
ListNode *current = head;
while (current != NULL && current->next != NULL) {
ListNode *temp = current->next;
current->next = current->next->next;
temp->next = current;
prev->next = temp;
prev = current;
current = current->next;
}
return fake_head.next;
}
I've stuck as close as possible to your original code there, but personally, I'd tighten it up a little further. In particular, you don't need to maintain both current and prev across iterations; just the latter would be sufficient.
ListNode* reverseListInPairs(ListNode *head) {
ListNode fake_head = { .next = head };
ListNode *prev = &fake_head;
while (prev->next && prev->next->next) {
ListNode *first = prev->next;
ListNode *second = first->next;
prev->next = second;
first->next = second->next;
second->next = first;
prev = first;
}
return fake_head.next;
}
Node *reverse (Node *head, int k)
{
Node* current = head;
Node* next = NULL;
Node* prev = NULL;
int count = 0;
while (current != NULL && count < k)
{
next = current->next;
current->next = prev;
prev = current;
current = next;
count++;
}
if (next != NULL)
head->next = reverse(next, k);
return prev;
}
pass the value of k is 2
void pairWiseSwap(struct Node* head)
{
struct Node* temp = head;
/* Traverse further only if there are at-least two nodes left */
while (temp != NULL && temp->next != NULL) {
/* Swap data of node with its next node's data */
swap(&temp->data, &temp->next->data);
/* Move temp by 2 for the next pair */
temp = temp->next->next;
}
}
Sourced from GeeksForGeeks.
As for what is the error, it has been pointed out that prev is already NULL.
ListNode *current = head,*newHead = NULL,*temp = NULL,*prev = NULL;
.
.
prev->next = temp;
We can't have NULL->next as it will throw a segmentation fault.
I'm writing a program to create a linked list(a node), then reverse it. The linked list contains data and the address of the next.
typedef struct node{
int data;
struct node *next;
}node;
Firstly, I create the linked list.
struct node *Insert_value(int dataInput,node* head)
{
node *new_node=NULL;
new_node = malloc(sizeof(node));
new_node -> next = head;
new_node -> data = dataInput;
head = new_node;
return head;
}
After that, i create a function to print these data. (i called it PrintNode)
while(head!= NULL)
{
printf("%d\t",head->data);
head= head->next;
}
printf("\n");
}
Finally, a function created to reverse the linked list.
struct node* Reversing(node **head)
{
node *current, *previous, *first;
current = previous = first = *head;
first = first->next->next;
current = current->next;
previous ->next = NULL;
current->next = previous;
while(first != NULL)
{
previous = current;
current = first;
first = first -> next;
previous->next = current;
}
return current;
}
It's my full program.
#include <stdio.h>
#include <stdlib.h>
typedef struct node{
int data;
struct node *next;
}node;
struct node *Insert_value(int dataInput,node* head);
struct node * Reversing(node **head);
void PrintNode(node *head);
main()
{
node *head = NULL;
int i=0,dataInput;
while(i!=5)
{
printf("input your elements: ");
scanf("%d",&dataInput);
head = Insert_value(dataInput,head);
i++;
}
PrintNode(head);
head = Reversing(&head);
PrintNode(head);
}
struct node *Insert_value(int dataInput,node* head)
{
node *new_node=NULL;
new_node = malloc(sizeof(node));
new_node -> next = head;
new_node -> data = dataInput;
head = new_node;
return head;
}
struct node* Reversing(node **head)
{
node *current, *previous, *first;
current = previous = first = *head;
first = first->next->next;
current = current->next;
previous ->next = NULL;
current->next = previous;
while(first != NULL)
{
previous = current;
current = first;
first = first -> next;
previous->next = current;
}
return current;
}
void PrintNode(node* head)
{
while(head!= NULL)
{
printf("%d\t",head->data);
head= head->next;
}
printf("\n");
}
After debugging lots of times, I know that these functions are fine. However, after the reverse function, the address of the next node of the head variable is NULL. Can you explain and give me some pieces of advice?
The one line change that will solve your problem will be (you visualized it a bit wrong).
current->next =previous;
in place of
previous->next = current;
Your code will blowup for single element linked list. Add a proper check for that in the function Reversing(). In case there is single element first->next will be NULL. But you wrote first->next->next which will be undefined behavior in case first->next is NULL.
In earlier case you were just creating a linked list in Reversing() with the links unchanged but head was pointing to the last node. So the next of it was NULL.
Modify Reversing such that new nodes are appended at the end. When going through the list, you need to save the next node ahead of time (node *next = current->next)
struct node* Reversing(node **head)
{
node *current = *head;
node *reverse = NULL;
while(current)
{
node *next = current->next;
if(!reverse)
{
reverse = current;
reverse->next = NULL;
}
else
{
current->next = reverse;
}
reverse = current;
current = next;
}
return reverse;
}
I want to reverse the last 5 nodes in a linked list as follows:
Input: 2->4->6->8->10->12->14->16->NULL
Output: 2->4->6->16->14->12->10->8->NULL
I have written the following code to perform the above task but my reverse() function is not working.
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node *next;
};
int n;
void insert(struct node **headref, int data) {
struct node *new_node;
new_node = malloc(sizeof(struct node));
new_node->data = data;
new_node->next = *headref;
*headref = new_node;
}
struct node* create() {
struct node dummy;
struct node *new_node = &dummy;
dummy.next = NULL;
int i,num;
printf("Enter The Number Of Data: ");
scanf("%d", &n);
for(i = 1; i <= n; i++) {
printf("Enter Data %d: ", i);
scanf("%d", &num);
insert(&(new_node->next), num);
new_node = new_node->next;
}
return dummy.next;
}
void display(struct node *head) {
struct node *current;
for(current = head; current != NULL; current = current->next) {
printf("%d ", current->data);
}
printf("\n");
}
void reverse(struct node *head) {
struct node *current, *next, *prev, *temp;
current = head;
next = current->next;
prev = NULL;
int i;
for(i = 0; i < n-5; i++) {
temp = current;
current = next;
next = next->next;
}
while(current != NULL) {
current->next = prev;
prev = current;
current = next;
next = next->next;
}
temp->next = prev;
}
int main() {
struct node *start = create();
display(start);
reverse(start);
display(start);
}
Is there any error in my logic in the reverse() function? I tried the dry run on paper and it should have worked but it isn't working. Please point out the mistake that I made or even better suggest some alternative code to solve this problem.
The problem is in the line:
next = next->next;
in this part of the code:
while(current != NULL) {
current->next = prev;
prev = current;
current = next;
next = next->next;
}
In the last element, when current becomes the last node current->next is NULL and you try to get next->next->next which gives segmentation fault.
You need to change the above line simply by adding an if statement:
while(current != NULL) {
current->next = prev;
prev = current;
current = next;
if (next!=NULL) next = next->next;
}
I tried with your given input and it works!!
I am trying to make my linked list program into a doubly linked list, however, am encountering a problem when I am trying to print my list backwards.
At the moment when I try to print backwards, it just runs a never ending loop, and I can't quite figure out where the error is.
If anyone can point out what I'm doing wrong it'd be very helpful.
EDIT: I believe the problem is in the displaybackwards method, but I do not know how to change it, as removing it would cause the program to crash.
These are the parts of my current code that I think the problem may be in:
struct NODE
{
union
{
int nodeCounter;
void *dataitem;
}item;
struct NODE *link;
struct NODE *backlink;
};
struct NODE *InitList()
{
struct NODE *temp = (struct NODE*)malloc(sizeof NODE);
temp->item.nodeCounter = 0;
temp->link = NULL;
temp->backlink = NULL;
return temp;
}
void Add2List(struct NODE *start, struct NODE *NewNode)
{
struct NODE *current = start;
while (current->link != NULL)
{
current->backlink = current; //problem should be this line
current = current->link;
}
current->link = NewNode;
NewNode->link = NULL;
NewNode->backlink = current;
start->item.nodeCounter++;
}
void DisplayList(struct NODE *start)
{
struct NODE *current = start->link;
while (current != NULL)
{
DisplayNode((struct inventory *)current->item.dataitem);
current = current->link;
}
}
void DisplayBackwards(struct NODE *start)
{
struct NODE *current = start->link;
while(current != NULL && current->link != NULL) //goes until current == last node
{
current = current->link;
current->backlink = current;
}
//when current == last node
while(current != start)// && current->backlink != NULL)
{
DisplayNode((struct inventory*)current->item.dataitem);
current->link = current;
current = current->backlink;
}
}
void DisplayBackwards(struct NODE *start)
{
struct NODE *current = start; //current points to first node
if(current==NULL) //if empty list, return
return;
//now we are sure that atleast one node exists
while(current->link != NULL) //goes until current == last node
{
current = current->link; //keep on going forward till end of list
}
//start from last node and keep going back till you cross the first node
while(current != NULL)
{
DisplayNode((struct inventory*)current->item.dataitem);
current = current->backlink; //go one node back
}
}
#include <stdio.h>
#include <stdlib.h>
struct node {
int val;
struct node* next;
} ;
struct node* largest(struct node** first)
{
struct node* largest = *first;
struct node* prev = NULL;
struct node* temp_prev = NULL;
for(;first != NULL; first = first -> next)
{
if (first -> val > largest -> val)
{
largest = first;
prev = temp_prev;
}
temp_prev = first;
}
if(prev != NULL)
prev -> next = largest -> next;
largest -> next = NULL;
return largest;
}
struct node* sel_sort(struct node** list)
{
struct node* head = NULL;
struct node* temp_largest = NULL;
while (*list)
{
head = largest(list);
head->next=temp_largest;
temp_largest = head;
}
*list = head; // note sets the input pointer to the new list.
return head;
}
void print_list(struct node* first)
{
struct node* temp;
for (temp = first; temp != NULL; temp = temp->next)
{
printf("%d\n", temp->val);
}
}
void main() {
struct node* r = malloc(sizeof(struct node));
struct node* s = malloc(sizeof(struct node));
struct node* t = malloc(sizeof(struct node));
struct node* w = malloc(sizeof(struct node));
struct node* q = malloc(sizeof(struct node));
r->val = 2;
r->next = s;
s->val = 10;
s->next = t;
t->next = w;
t->val = 3;
w->val = 1;
w->next = q;
q->val = 6;
q->next = NULL;
printf("\nBefore Sort:\n");
print_list(r);
printf("\nSorted:\n");
struct node* sorted = sel_sort(&r);
print_list(sorted);
}
In short, the above is selection sort for a singly linked list. I'm having an issue where an infinite loops occurs in the sel_sort method, because no matter how many times I call the largest method, one node will be left in the original list. Other then that my code seems to work, but how do I get around this small problem?
So, what do you expect will ever modify the variable list in this while-loop:
struct node* temp = *list;
struct node* head;
struct node* temp_largest = NULL;
while (list != NULL) // <<=== infinite loop
{
head = largest(temp);
head->next=temp_largest;
temp_largest = head;
}
return head;
I question your use of temp. Technically your largest() function should take a list head by address (pointer to pointer), extract the largest node, returning that node after removal from the list, and updating the passed-in list head on the off-chance it was the first node in the list (therefore the head has to be moved):
struct node* head = NULL;
struct node* temp_largest = NULL;
while (*list)
{
head = largest(list);
head->next=temp_largest;
temp_largest = head;
}
*list = head; // note sets the input pointer to the new list.
return head;
And have largest() take a list pointer by address (a double pointer)
struct node* largest(struct node** first)
{
struct node *prev = NULL;
struct node *lprev = NULL;
struct node *cur = NULL;
struct node *largest = NULL;
if (!(first && *first))
return NULL;
// assume the first node is the largest node
largest = lprev = prev = *first;
cur = largest->next;
for(; cur; prev = cur, cur = cur->next)
{
if (cur->val > largest->val)
{
largest = cur;
lprev = prev;
}
}
// go with the simple stuff first. was `largest`
// the first item in the list?
if (largest == *first)
{
// yes it was, so move the list head.
*first = largest->next;
}
else
{ // no it was not, so link `lprev` to be
// the node following `largest`
lprev->next = largest->next;
}
// regardless. always unlink the largest node.
largest->next = NULL;
return largest;
}
Using this in combination with the updated sort, I get this for output:
Output
Before Sort:
2
10
3
1
6
Sorted:
1
2
3
6
10