Question
Middle node of a linked list
i am trying to return a middle node of linked-list, it works well when number of nodes are even and when number of nodes are odd, segmentation fault is all i see. initially i return slow if fast reached NULL, but it still fails for odd number of nodes. i tried two conditions: 1. if fast reached NULL AND length of linked-list is even: return slow 2. if fast reach NULL AND length of linked-list is odd: return slow->next. i also run gdb which points the seg fault to: fast = fast->next->next; in the middle_node(node *) function. Appreciate.
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef struct node
{
// holds number of type int
int number;
// holds pointer to node of the same type
struct node *next;
} node;
int count = 0;
// insert/tuck new node into the existing linked list
node *insert(node *, int);
// delete entire linked list
bool destroy(node *);
// return size of linked-list
int list_size(node *);
// return middle node of linked list
node *middle_node(node *);
int main(void)
{
// declare head node
node *list = NULL;
// inserting into linked list with a loop var
for (int i = 0; i < 11; i++)
{
list = insert(list, 1 + i);
}
node *middle = NULL;
middle = middle_node(list);
printf("node: %p, value: %i\n", middle, middle->number);
// destroy/free heaps
destroy(list);
}
// insert/tuck new node into the existing linked list
node *insert(node *head, int x)
{
// 1 dynamically allocate space for the new node
node *new = (node *)malloc(sizeof(node));
// 2 check to make sure we didnt run out of memory
if (new == NULL)
{
return 0; // NULL
}
// 3 populate and insert the node at the beginning of the linked list
new->number = x;
// 3B arrange/connect the pointers in the correct order
// connect new element's next pointer to head first
new->next = head;
// set head to point to new element
head = new;
// 4 return a pointer to the new head of linked list
return head;
}
// delete/free entire singly linked list
bool destroy(node *head)
{
// 1 if youve reach a NULL pointer, stop
if (head != NULL)
{
// 2 else: delete the rest of the list (recursively)
destroy(head->next);
// 3 free the current node
free(head);
return true;
}
return false;
}
// return size of linked list
int list_size(node *head)
{
// return size of linked list
// temp points to head of list
node *temp = head;
int size = 0;
while (temp != NULL)
{
size += 1;
temp = temp->next;
}
return size;
}
// return middle node of linked list
node *middle_node(node *head)
{
// declare to pointers fast and slow of type node *
if (head != NULL)
{
node *slow = NULL, *fast = NULL, *current = NULL;
slow = head;
fast = head;
current = head;
while (current != NULL)
{
count++;
// one step at a time
slow = slow->next;
// two step at a time
fast = fast->next->next;
// when fast points to last node
if ((fast == NULL) && (list_size(head) % 2 == 1))
{
// return slow as the middle node
return slow->next;
}
if ((fast == NULL) && (list_size(head) % 2 == 0))
{
return slow;
}
// else update current node one step forward
current = current->next;
}
}
else
{
// return NULL otherwise
return NULL;
}
}