Reputation: 50
I was asked to write a function reverseHalves() that rearranges a given linked list so that the first half of the nodes is moved to the back of the second half. e.g.
Given a linked list [1 2 3 4 5 6]
, the resulting list should be [4 5 6 1 2 3]
.
When given a linked list with an odd number of nodes, the list should be split with the first half having an additional node. That is, given the list [1 2 3 4 5]
, the resulting list should be [4 5 1 2 3]
.
But the my function will give a infinite output...
typedef struct _listnode{
int item;
struct _listnode *next;
} ListNode;
typedef struct _linkedlist{
int size;
ListNode *head;
ListNode *tail;
} LinkedList;
Here are the functions I used:
// printList will print out the value in every nodes until there is a NULL
void printList(LinkedList *ll);
ListNode * findNode(LinkedList *ll, int index);
int insertNode(LinkedList *ll, int index, int value);
void reverseHalves(LinkedList *ll)
{
int index;
ListNode *new_head, *new_tail;
new_head = NULL;
new_tail = NULL;
// determine the index of new tail, and the new head which is index+1*
index = (ll->size + 1) / 2;
// get the new head by findNode func,whose index is index+1
// make new_head point to the node found*
new_head = findNode(ll, index);
// make initial tail->next be the initial head*
ll->tail->next = ll->head;
// set the head to be the new head
ll->head = new_head;
insertNode(ll, ll->size, -1);
new_tail = findNode(ll, ll->size);
new_tail = NULL;
}
Upvotes: 0
Views: 3500
Reputation: 31
Here's the code for reversing second half(right) of linked list.
#include<stdio.h>
#include<stdlib.h>
struct Node{
int data;
struct Node* next;
};
void append(struct Node** head_ref, int new_data)
{
struct Node* new_node=(struct Node*)malloc(sizeof(struct Node));
new_node->data=new_data;
new_node->next=NULL;
struct Node* last=*head_ref;
if(*head_ref==NULL){
*head_ref=new_node;
return;
}
while(last->next!=NULL)
last=last->next;
last->next=new_node;
return;
}
int display(struct Node* n)
{
int m=0;
printf("\n");
while(n!=NULL)
{
printf(" %d ",n->data);
n=n->next;
m=m+1;
}
return m;
}
void reverse(struct Node** head_ref, int mid)
{
if(*head_ref==NULL)
{
printf("\nEmpty List cannot be reversed");
return;
}
struct Node* last=*head_ref;
struct Node* second_last;
struct Node* beg=*head_ref;
int c=1;
while(c<=mid){
second_last=last;
last=last->next;
c=c+1;
}
struct Node* prev=NULL;
struct Node* current=last;
struct Node* next;
while(current != NULL)
{
next=current->next;
current->next=prev;
prev=current;
current=next;
}
*head_ref=beg;
second_last->next=prev;
}
int main()
{
int size;
struct Node* head=NULL;
int i,mid;
for(i=0;i<11;i++)
{
append(&head,rand()%19 +1);
}
size=display(head);
printf("\n Size of linked list: %d",size);
if(size%2==0)
mid=(size+1)/2;
else
mid=size/2;
reverse(&head, mid);
display(head);
return 0;
}
Upvotes: 0
Reputation: 2625
I would advice you to code the problem in steps.
1)Firstly create a list.
2)split the list ,to get two lists.
3)add the tail of the second list to the head of the first list.
Upvotes: 1
Reputation: 1002
This is an approximate gist:
new_head_index = (ll->size+1) / 2;
new_tail_index = new_head_index - 1;
if (new_tail_index < 0)
return;
new_head = findNode(ll,new_head_index);
new_tail = findNode(ll,new_tail_index);
ll->tail->next = ll->head;
new_tail->next = NULL
ll->head = new_head;
Upvotes: 0