Вы находитесь на странице: 1из 6

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 : 1(ptr1,ptr2) -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 ->
10

STEP 2 : 1(ptr2) -> 2 -> 3 -> 4 -> 5 -> 6(ptr1) -> 7 -> 8 -> 9 -
> 10

Now, start the second pointer (ptr2) and keep on incrementing it till the first pointer (ptr1) reaches the
end of the LL.

STEP 3 : 1 -> 2 -> 3 -> 4(ptr2) -> 5 -> 6 -> 7 -> 8 -> 9 -> 10 (
ptr1)

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

Вам также может понравиться