Check if a Linked List is a Palindrome in C

 

Check if a Linked List is a Palindrome in C

This program demonstrates how to determine whether a singly linked list is a palindrome. A palindrome is a sequence that reads the same forward and backward. The challenge is to efficiently check this condition without converting the entire list into an array.

Program Explanation

The program is built around a linked list node structure and includes functions for adding nodes to the list, checking for palindrome properties, and displaying the list. It utilizes a fast and slow pointer technique to find the middle of the list, then reverses the second half of the list and compares it with the first half.

  • struct Node: Represents each node in the linked list, containing an integer data and a pointer to the next node.
  • push: Adds a new node to the front of the list.
  • isPalindrome: Checks if the list is a palindrome.
  • printList: Displays the content of the linked list.

Source Code


#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

struct Node {
    int data;
    struct Node* next;
};

// Function to add a node at the front of the list
void push(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 = (*head_ref);
    (*head_ref) = new_node;
}

// Function to check if the linked list is a palindrome
bool isPalindrome(struct Node* head) {
    struct Node *slow_ptr = head, *fast_ptr = head;
    struct Node *second_half, *prev_of_slow_ptr = head;
    struct Node *midnode = NULL;  // To handle odd size list
    bool result = true;  // Initialize result as true

    if (head != NULL && head->next != NULL) {
        // Get the middle of the list
        while (fast_ptr != NULL && fast_ptr->next != NULL) {
            fast_ptr = fast_ptr->next->next;
            prev_of_slow_ptr = slow_ptr;
            slow_ptr = slow_ptr->next;
        }

        // For odd sized lists, skip the middle node
        if (fast_ptr != NULL) {
            midnode = slow_ptr;
            slow_ptr = slow_ptr->next;
        }

        // Reverse the second half of the list
        second_half = slow_ptr;
        prev_of_slow_ptr->next = NULL;  // NULL terminate the first half
        struct Node* prev = NULL;
        struct Node* current = second_half;
        struct Node* next;
        while (current != NULL) {
            next = current->next;
            current->next = prev;
            prev = current;
            current = next;
        }
        second_half = prev;

        // Compare the two halves
        while (head != NULL && second_half != NULL) {
            if (head->data != second_half->data) {
                result = false;
                break;
            }
            head = head->next;
            second_half = second_half->next;
        }

        // Reconstruct the original list by reversing the second half again
        if (midnode != NULL) {
            prev_of_slow_ptr->next = midnode;
            midnode->next = prev;
        } else {
            prev_of_slow_ptr->next = prev;
        }
    }
    return result;
}

// Function to print nodes in a given linked list
void printList(struct Node* ptr) {
    while (ptr != NULL) {
        printf("%d -> ", ptr->data);
        ptr = ptr->next;
    }
    printf("NULL\\n");
}

int main() {
    struct Node* head = NULL;
    push(&head, 1);
    push(&head, 2);
    push(&head, 3);
    push(&head, 2);
    push(&head, 1);

    printf("Given linked list\\n");
    printList(head);

    if (isPalindrome(head)) {
        printf("Linked list is a palindrome.\\n");
    } else {
        printf("Linked list is not a palindrome.\\n");
    }

    return 0;
}
        

Conclusion

The provided C program checks if a linked list is a palindrome by using a fast and slow pointer technique to efficiently find the middle, reverse the second half, and then compare segments. This method minimizes space complexity by avoiding the need to convert the list into a different data structure and is efficient in terms of time complexity.

 

Leave a Reply

Your email address will not be published. Required fields are marked *