Recently I came across a very interesting question on Link Lists. I tried a lot of crap before i got a click and I solved the problem. The problem can be stated as follows
We are given a singly-linked list A. The nodes of A consists of usual data and next pointer. Along with these there is another pointer random which points to a random node of A. We are supposed to make a new linked list B which is copy of A as far as the structure is concerned but all its nodes are newly allocated. Develop an algorithm such that its time complexity is O(n).
Following is my solution coded in C. I thoroughly enjoyed solving the problem and urge everyone to try to solve it yourself. You will surely get to the solution.
/*
* duplicate_link_list.c
*
* duplicates a given link list where each node has a next pointer
* and a random pointer pointing to any node in the link list
*
*/
#include <assert.h>
#include <malloc.h>
#include <stdlib.h>
#include <stdio.h>
typedef struct _node Node;
struct _node {
int data;
Node *next;
Node *random;
};
/*
* duplicates link list given as src and put the duplicate into
* *dst
*
* assumes the link list are having sentinal elements
*
*/
void duplicate(Node *src, Node **dst) {
Node *i_s, *i_d, *t;
assert(*dst != NULL);
/* FIRST PASS Allocate new nodes */
i_s = src;
i_d = *dst;
i_s = i_s->next;
while(i_s)
{
t = (Node *)malloc(sizeof(Node) * 1);
assert(t != NULL);
t->data = i_s->data;
t->next = i_s->random;
t->random = NULL;
i_s->random = t;
i_s = i_s->next;
}
/* SECOND PASS: Adjust all new nodes to have there
* correct random pointers
*/
i_s = src->next;
while(i_s)
{
Node *n;
n = i_s->random;
n->random = (n->next)->random;
i_s = i_s->next;
}
/* THIRD PASS: Unzip the teo link lists */
i_s = src->next;
i_d = *dst;
while(i_s)
{
t = i_s->random;
i_s->random = t->next;
t->next = NULL;
i_d->next = t;
i_d = t;
i_s = i_s->next;
}
}
t->data = i_s->data;
t->next = i_s->random;
t->random = NULL;
i_s->random = t;
i_s = i_s->next;
}
/* SECOND PASS: Adjust all new nodes to have there
* correct random pointers
*/
i_s = src->next;
while(i_s)
{
Node *n;
n = i_s->random;
n->random = (n->next)->random;
i_s = i_s->next;
}
/* THIRD PASS: Unzip the teo link lists */
i_s = src->next;
i_d = *dst;
while(i_s)
{
t = i_s->random;
i_s->random = t->next;
t->next = NULL;
i_d->next = t;
i_d = t;
i_s = i_s->next;
}
}
6 comments:
sabash rahul.....
sabash rahul...........
this code is unreadable.. you should have explained the algo and let the reader implement it if they needed to!
@Anonymous, Thanks for pointing out my mistake. I have corrected the post by reformatting the code.
Work of a genius. I took time to understand the third pass. To save some time, we could've remove t->random = NULL in 1st pass and t->next = NULL in 3rd pass and instead add i_d->next = NULL after the while loop (assuming sentinel elements).
Post a Comment