The recursion can work with a pointers to the last half of the list, a pointer to the beginning of the list and a pointer to an integer to capture non-matching data.
One pointer advances to next
as the recursion progresses and arrives at the end of the list.
The other pointer advances to next
as the recursion returns.
#include <stdio.h>
#include <stdlib.h>
typedef struct list_s list;
struct list_s {
int data;
list *next;
};
list *is_palindrome ( list *forward, list *backward, int *match) {
list *going = forward;
if ( ! going) {
return backward;
}
list *coming = is_palindrome ( forward->next, backward, match);
if ( *match) { // so far data matches
printf ( "compare data: %d %d\n", going->data, coming->data);
*match = ( going->data == coming->data); // 1 matches 0 not matching
}
return coming->next;
}
int main ( void) {
int palindrome = 1;
int items[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 118, 7, 6, 5, 4, 3, 2, 1};
int size = sizeof items / sizeof *items;
list *head = NULL;
for ( int each = 0; each < size; ++each) {
list *element = NULL;
if ( NULL == ( element = malloc ( sizeof *element))) {
fprintf ( stderr, "problem malloc\n");
return 1;
}
element->next = NULL;
element->data = items[each];
if ( head) {
element->next = head;
head = element;
}
else {
head = element;
}
}
list *half = head;
int toggle = 0;
printf ( "list contents:\n");
list *temp = head;
while ( temp) {
toggle = ! toggle;
if ( toggle) {
half = half->next; // alternately advance to middle of list
}
printf ( "%d ", temp->data);
temp = temp->next;
}
printf ( "\n");
is_palindrome ( half, head, &palindrome);
if ( palindrome) {
printf ( "is a palindrone\n");
}
else {
printf ( "is not a palindrone\n");
}
while ( head) {
list *temp = head;
head = head->next;
free ( temp);
}
head = NULL;
return 0;
}