Suppose our linked list contains integer values and is described as:
1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8
and if we want to reverse 2 elements at a time then modified linked list should be:
2 -> 1 -> 4 -> 3 -> 6 -> 5 -> 8 -> 7
and if we want to reverse 3 elements at a time then modified linked list should be:
3 -> 2 -> 1 -> 6 -> 5 -> 4 -> 7 -> 8
Here in case where k=3 last 2 elements are not reversed because 2<3.
We will use recursive algorithm to implement above reversal. Assume List Node's defination as:
//Node Data
typedef struct _DATA
{
int key;
}DATA,*PDATA;
//Node Struct
typedef struct _NODE
{
DATA item;
struct _node *pnext;
}NODE,*PNODE;
//
//Helper functions
//
PNODE NewNode(DATA item);
PNODE InsertAtStart(PNODE phead,DATA item);
PNODE DeleteAtStart(PNODE phead,PDATA pdata);
void Traverse(PNODE phead);
void DeleteList(PNODE phead);
//Reverses linked list pointed by phead
PNODE Reverse(PNODE phead);
//
// First reverse first k nodes then reverse N-k nodes
// recursively where N=total size of list
//
PNODE ReverseKNodesAtATime(PNODE phead,int k)
{
PNODE temp=phead;
int count=k;
// Move to kth node from starting
while(temp && --count)
{
temp=temp->pnext;
}
if(temp)
{
/*remaining list containing N-k nodes head*/
PNODE nextstart=temp->pnext;
/* set end of list of first k nodes to NULL*/
temp->pnext=NULL;
/* newHead is head of list of first k nodes after reversal*/
PNODE newHead=Reverse(phead);
/*Now phead points to end of first k nodes list after reversal*/
phead->pnext=ReverseKNodesAtATime(nextstart,k);
return newHead;
}
else
{
return phead;
}
}
//
// Finds and returns kth element from end of list if exist else returns NULL
//
PNODE LastKthNode(PNODE phead,int k)
{
PNODE back=phead,
front=phead;
if(k<1)
return NULL;
else
{
// move front forward till number of nodes between
// front and back becomes not equal to k-1
while(front && k--)
{
front=front->pnext;
}
if(k!=-1)
{
if(!front)
printf("Error\n");
else
return NULL;
}
else
{
// when front becomes null, our back points to last kth
// nodes because initial difference of k-1 nodes
while(front)
{
front=front->pnext;
back=back->pnext;
}
return back;
}
}
}
int main(void)
{
PNODE phead=NULL;
DATA d;
int i;
//insert 10 elements
for(i=1;i<=10;i++)
{
d.key=i;
phead=InsertAtStart(phead,d);
}
phead=Reverse(phead);
printf("List Reversed\n");
Traverse(phead);
printf("Reversed 2 at a time\n");
phead=ReverseKNodesAtATime(phead,2);
Traverse(phead);
PNODE pLastkthNode=LastKthNode(phead,6);
if(pLastkthNode)
{
printf("Last 6th node: %d\n",pLastkthNode->item.key);
}
else
{
printf("Last 6th node doesn't exist\n");
}
DeleteList(phead);
return 0;
}
PNODE Reverse(PNODE phead)
{
PNODE ptail,pmiddle;
ptail=pmiddle=NULL;
while(phead)
{
ptail=pmiddle;
pmiddle=phead;
phead=phead->pnext;
pmiddle->pnext=ptail;
}
return pmiddle;
}
PNODE NewNode(DATA item)
{
PNODE pnode=(PNODE)malloc(sizeof(NODE));
if(pnode)
{
pnode->item=item;
pnode->pnext=NULL;
}
return pnode;
}
PNODE InsertAtStart(PNODE phead,DATA item)
{
if(!phead)
{
PNODE pnode=NewNode(item);
if(!pnode)
printf("Failed to allocate memory\n");
return pnode;
}
else
{
PNODE pnewNode=NewNode(item);
if(pnewNode)
pnewNode->pnext=phead;
else
printf("Failed to allocate memory\n");
}
}
PNODE DeleteAtStart(PNODE phead,PDATA pdata)
{
if(!phead)
return phead;
else
{
PNODE pnext=phead->pnext;
*pdata=phead->item;
free(phead);
return pnext;
}
}
void Traverse(PNODE phead)
{
while(phead)
{
printf("%d\n",phead->item.key);
phead=phead->pnext;
}
}
void DeleteList(PNODE phead)
{
while(phead)
{
PNODE ptemp=phead;
phead=phead->pnext;
free(ptemp);
}
}
1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8
and if we want to reverse 2 elements at a time then modified linked list should be:
2 -> 1 -> 4 -> 3 -> 6 -> 5 -> 8 -> 7
and if we want to reverse 3 elements at a time then modified linked list should be:
3 -> 2 -> 1 -> 6 -> 5 -> 4 -> 7 -> 8
Here in case where k=3 last 2 elements are not reversed because 2<3.
We will use recursive algorithm to implement above reversal. Assume List Node's defination as:
//Node Data
typedef struct _DATA
{
int key;
}DATA,*PDATA;
//Node Struct
typedef struct _NODE
{
DATA item;
struct _node *pnext;
}NODE,*PNODE;
//
//Helper functions
//
PNODE NewNode(DATA item);
PNODE InsertAtStart(PNODE phead,DATA item);
PNODE DeleteAtStart(PNODE phead,PDATA pdata);
void Traverse(PNODE phead);
void DeleteList(PNODE phead);
//Reverses linked list pointed by phead
PNODE Reverse(PNODE phead);
//
// First reverse first k nodes then reverse N-k nodes
// recursively where N=total size of list
//
PNODE ReverseKNodesAtATime(PNODE phead,int k)
{
PNODE temp=phead;
int count=k;
// Move to kth node from starting
while(temp && --count)
{
temp=temp->pnext;
}
if(temp)
{
/*remaining list containing N-k nodes head*/
PNODE nextstart=temp->pnext;
/* set end of list of first k nodes to NULL*/
temp->pnext=NULL;
/* newHead is head of list of first k nodes after reversal*/
PNODE newHead=Reverse(phead);
/*Now phead points to end of first k nodes list after reversal*/
phead->pnext=ReverseKNodesAtATime(nextstart,k);
return newHead;
}
else
{
return phead;
}
}
//
// Finds and returns kth element from end of list if exist else returns NULL
//
PNODE LastKthNode(PNODE phead,int k)
{
PNODE back=phead,
front=phead;
if(k<1)
return NULL;
else
{
// move front forward till number of nodes between
// front and back becomes not equal to k-1
while(front && k--)
{
front=front->pnext;
}
if(k!=-1)
{
if(!front)
printf("Error\n");
else
return NULL;
}
else
{
// when front becomes null, our back points to last kth
// nodes because initial difference of k-1 nodes
while(front)
{
front=front->pnext;
back=back->pnext;
}
return back;
}
}
}
{
PNODE phead=NULL;
DATA d;
int i;
//insert 10 elements
for(i=1;i<=10;i++)
{
d.key=i;
phead=InsertAtStart(phead,d);
}
phead=Reverse(phead);
printf("List Reversed\n");
Traverse(phead);
printf("Reversed 2 at a time\n");
phead=ReverseKNodesAtATime(phead,2);
Traverse(phead);
PNODE pLastkthNode=LastKthNode(phead,6);
if(pLastkthNode)
{
printf("Last 6th node: %d\n",pLastkthNode->item.key);
}
else
{
printf("Last 6th node doesn't exist\n");
}
DeleteList(phead);
return 0;
}
PNODE Reverse(PNODE phead)
{
PNODE ptail,pmiddle;
ptail=pmiddle=NULL;
while(phead)
{
ptail=pmiddle;
pmiddle=phead;
phead=phead->pnext;
pmiddle->pnext=ptail;
}
return pmiddle;
}
PNODE NewNode(DATA item)
{
PNODE pnode=(PNODE)malloc(sizeof(NODE));
if(pnode)
{
pnode->item=item;
pnode->pnext=NULL;
}
return pnode;
}
PNODE InsertAtStart(PNODE phead,DATA item)
{
if(!phead)
{
PNODE pnode=NewNode(item);
if(!pnode)
printf("Failed to allocate memory\n");
return pnode;
}
else
{
PNODE pnewNode=NewNode(item);
if(pnewNode)
pnewNode->pnext=phead;
else
printf("Failed to allocate memory\n");
}
}
PNODE DeleteAtStart(PNODE phead,PDATA pdata)
{
if(!phead)
return phead;
else
{
PNODE pnext=phead->pnext;
*pdata=phead->item;
free(phead);
return pnext;
}
}
void Traverse(PNODE phead)
{
while(phead)
{
printf("%d\n",phead->item.key);
phead=phead->pnext;
}
}
void DeleteList(PNODE phead)
{
while(phead)
{
PNODE ptemp=phead;
phead=phead->pnext;
free(ptemp);
}
}
Please ask for doubt if any. Thank you.
No comments:
Post a Comment