Reverse a singly linked list p = head; q = p->next; p->next = (mynode *)0; while (q !

= (mynode *)0) { r = q->next; q->next = p; p = q; q = r; } head = p; Reverse the linked list recursively mynode* reverse_recurse(mynode *root) { if(root->next!=(mynode *)0) { reverse_recurse(root->next); root->next->next=root; return(root); } else { head=root; } } Given only a pointer to a node to be deleted in a singly linked list, how do you delete it? The solution to this is to copy the data from the next node into this node and delete the next node!. Ofcourse this wont work if the node to be deleted is the last node. Mark it as dummy in that case. How do you reverse a linked list without using any C pointers? One way is to reverse the data in the nodes without changing the pointers themselves. One can also create a new linked list which is the reverse of the original linked list.

How would you detect a loop in a linked list? Write a C program to detect a loop in a linked list. Have 2 pointers to start of the linked list. Increment one pointer by 1 node and the other by 2 nodes. If there's a loop, the 2nd pointer will meet the 1st pointer somewhere. If it does, then you know there's one. p=head; q=head->next; while(p!=NULL && q!=NULL) { if(p==q) { //Loop detected! exit(0); } p=p->next; q=(q->next)?(q->next->next):q->next; } Second approach would be, reverse the list. If you meet the head in the process of reversal, you’ve got a cycle. The exit condition, when you do not find a cycle is when you reach the tail node. How do you find the middle of a linked list? Have 2 pointers. p moves one step, where as q moves two steps, when q reaches end, p will be at the middle of the linked list. How to create a copy of a linked list ? copy_linked_lists(struct node *q, struct node **s) { if(q!=NULL) { *s=malloc(sizeof(struct node)); (*s)->data=q->data; (*s)->link=NULL; copy_linked_list(q->link, &((*s)->link)); } } Write a C program to insert nodes into a linked list in a sorted fashion The solution is to iterate down the list looking for the correct place to insert the new node. That could be the end of the list, or a point just before a node which is larger than the new node.

Write a C program to free the nodes of a linked list This is the wrong way to do it struct list *listptr, *nextptr; for(listptr = head; listptr != NULL; listptr = listptr->next) { free(listptr); } This is the right way to do it struct list *listptr, *nextptr; for(listptr = head; listptr != NULL; listptr = nextptr) { nextptr = listptr->next; free(listptr); } head = NULL; Can we do a Binary search on a linked list? The answer is ofcourse, you can write a C program to do this. But, the question is, do you really think it will be as efficient as a C program which does a binary search on an array? Think hard, real hard. Do you know what exactly makes the binary search on an array so fast and efficient? Its the ability to access any element in the array in constant time. This is what makes it so fast. You can get to the middle of the array just by saying array[middle]!. Now, can you do the same with a linked list? The answer is No. You will have to write your own, possibly inefficient algorithm to get the value of the middle node of a linked list. In a linked list, you loosse the ability to get the value of any node in a constant time. One solution to the inefficiency of getting the middle of the linked list during a binary search is to have the first node contain one additional pointer that points to the node in the middle. Decide at the first node if you need to check the first or the second half of the linked list. Continue doing that with each half-list. How to read a singly linked list backwards?

Use recursion. Write a C program to return the nth node from the end of a linked list. Suppose one needs to get to the 6th node from the end in this LL. First, just keep on incrementing the first pointer (ptr1) till the number of increments cross n (which is 6 in this case) STEP 1 10 STEP 2 > 10 : : 1(ptr1,ptr2) -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> 1(ptr2) -> 2 -> 3 -> 4 -> 5 -> 6(ptr1) -> 7 -> 8 -> 9 -

Now, start the second pointer (ptr2) and keep on incrementing it till the first pointer (ptr1) reaches the end of the LL. STEP 3 ptr1) : 1 -> 2 -> 3 -> 4(ptr2) -> 5 -> 6 -> 7 -> 8 -> 9 -> 10 (

Write a C program to remove duplicates from a sorted linked list As the linked list is sorted, we can start from the beginning of the list and compare adjacent nodes. When adjacent nodes are the same, remove the second one. There's a tricky case where the node after the next node needs to be noted before the deletion. void RemoveDuplicates(struct node* head) { struct node* current = head; if (current == NULL) return; // do nothing if the list is empty // Compare current node with next node while(current->next!=NULL) { if (current->data == current->next->data) { struct node* nextNext = current->next->next; free(current->next); current->next = nextNext; } else { current = current->next; // only advance if no deletion } } }

Insertion before a node 1) Start at the head and traverse it to desired point. This operation is expensive since running time is proportional to length of list. 2) Insert the node q after p. Then swap the information in p and q. Problem can be if the information fields are large and fatal if other variables elsewhere in program points to either of the two nodes. 3) Keep second pointer(r) in lock step with p. Now q is just insert between r and p. Common point of 2 merging list If I have a list say with elements 1 2 3 4 5 6 and another list with element 7 and it merges with first list at 4 how to get the common point 4 Traverse the first and count the number of elements in it L1 = 6 in this case. Traverse the second list till end L2 = 4 L1 – L2 = 6 - 4 = 2 Advance the point p in bigger list by 2 and then start another point q in second list and traverse each node. Compare the nodes as you advance each pointer. If the list merge then at one point these 2 pointers will have command element.

Find whether or not there is a cylcle in a linked list? If so, Fix the cycle. N0 N2
0--->1---->2---->3---->4---->5---->6 | | | | N3 11< ---10<---9<---8 N1

Above figure shows how the orignal list (with a cycle) will look like. The goal is to fix the cycle. This can be done by finding N3 and setting N3->Next to NULL. The question is how to we find this. N0 is the head. Run one of the Two-Pointer cycle finding methods that I disscussed before on this list. The two pointers will meet somewhere inside the loop (3-4-5-……10-11-3). Lets call the node that the pointers meet as N1. Once the two pointers meet, hold one of the pointers(P1) at N1 and let the other other pointer(P2) traverse the cycle once, while keeping a count of the number of nodes in the cycle. Let the number of nodes in the cylce be x. Now, point pointer P2 to the head of the list (N0) and run the traverse the list until you find N1 while keeping a count of the number of nodes from the head N0 to N1. Lets this number be y (number of nodes from N0 toN1) Now Reverse the list. The list would look like :
N0 N2 0--->1—->2—->3< ----4<----5<----6 | | | | N3 11--->10—->9—->8 N1

After reversal get a count of nodes from N0 to N1. Let this number be z. The idea is to get the number of nodes from N0 to N2. Once we have this, we can get the address of N2 and then traverse the list in the loop, until we find a Node whose next is N2 and then set it to NULL. To solve this: Our Variables: Number of Nodes from N0 to N1 before reversal = y Number of Nodes from N0 to N1 after reversal = z Number of Nodes in the loop = x Numver of Nodes from N0 to N2 = k We need to solve for k. We have the following equation at hand. y + z = 2k + x (This equation could differ slightly if the number of nodes caluclated were inclusive of the nodes or not) k = (y + z - x) / 2