检查单向链表是否为回文 C
Check if a singly linked list is a palindrome or not in C
我正在尝试检查单向链表是否为回文。约束是 - 算法必须在线性时间和常数 space.
我使用的基本算法如下 -
- 使用快慢指针将链表分成两半
- 原地逆转下半场
- 比较上半场和下半场。
- 构造回原始列表
- Return结果。
当列表中的元素数量为偶数时我的实现有效,但如果元素数量为奇数则失败。
/*
* @brief Checks if a list is a palindrome or not
*/
bool is_palindrome(node *head)
{
node *first; /* Points to head node of 1st half */
node *second; /* Points to head node of 2nd half */
node *f_ptr = head; /* Fast pointer */
node *s_ptr = head; /* Slow pointer */
node *prev = NULL; /* Previous to slow pointer */
bool ret = false; /* Return value */
while (f_ptr && f_ptr->next && f_ptr->next->next)
{
prev = s_ptr;
s_ptr = s_ptr->next;
f_ptr = f_ptr->next->next;
}
/* List with even number of elements */
if (!(f_ptr->next->next))
{
first = head;
second = s_ptr->next;
s_ptr->next = NULL;
/* Reverse the second half */
second = reverse_list(&second);
/* Compare the first & second half */
ret = are_identical(first, second);
/* Finally, construct the original list back */
second = reverse_list(&second);
s_ptr->next = second;
print_list(head);
}
/* List with odd number of elements */
if (!(f_ptr->next))
{
first = head;
second = s_ptr->next;
prev->next = NULL;
s_ptr->next = NULL;
/* Reverse the second half */
second = reverse_list(&second);
/* Compare the first & second half */
ret = are_identical(first, second);
/* Finally, construct the original list back */
second = reverse_list(&second);
prev->next = s_ptr; s_ptr->next = second;
print_list(head);
}
return ret;
}
有人可以帮我弄清楚我在处理奇数案件时做错了什么吗?可以找到此程序的完整实现 here.
感谢 s7amuser 指出错误。以下是适用于偶数和奇数情况的实现。
/*
* @brief Checks if a list is a palindrome or not
*/
bool is_palindrome(node *head)
{
node *first; /* Points to head node of 1st half */
node *second; /* Points to head node of 2nd half */
node *f_ptr = head; /* Fast pointer */
node *s_ptr = head; /* Slow pointer */
node *prev = NULL; /* Previous to slow pointer */
bool ret = false; /* Return value */
while (f_ptr && f_ptr->next && f_ptr->next->next)
{
prev = s_ptr;
s_ptr = s_ptr->next;
f_ptr = f_ptr->next->next;
}
/* List with odd number of elements */
if (!(f_ptr->next))
{
first = head;
second = s_ptr->next;
prev->next = NULL;
s_ptr->next = NULL;
/* Reverse the second half */
second = reverse_list(&second);
/* Compare the first & second half */
ret = are_identical(first, second);
/* Finally, construct the original list back */
second = reverse_list(&second);
prev->next = s_ptr; s_ptr->next = second;
print_list(head);
}
/* List with even number of elements */
else if (!(f_ptr->next->next))
{
first = head;
second = s_ptr->next;
s_ptr->next = NULL;
/* Reverse the second half */
second = reverse_list(&second);
/* Compare the first & second half */
ret = are_identical(first, second);
/* Finally, construct the original list back */
second = reverse_list(&second);
s_ptr->next = second;
print_list(head);
}
return ret;
}
我正在尝试检查单向链表是否为回文。约束是 - 算法必须在线性时间和常数 space.
我使用的基本算法如下 -
- 使用快慢指针将链表分成两半
- 原地逆转下半场
- 比较上半场和下半场。
- 构造回原始列表
- Return结果。
当列表中的元素数量为偶数时我的实现有效,但如果元素数量为奇数则失败。
/*
* @brief Checks if a list is a palindrome or not
*/
bool is_palindrome(node *head)
{
node *first; /* Points to head node of 1st half */
node *second; /* Points to head node of 2nd half */
node *f_ptr = head; /* Fast pointer */
node *s_ptr = head; /* Slow pointer */
node *prev = NULL; /* Previous to slow pointer */
bool ret = false; /* Return value */
while (f_ptr && f_ptr->next && f_ptr->next->next)
{
prev = s_ptr;
s_ptr = s_ptr->next;
f_ptr = f_ptr->next->next;
}
/* List with even number of elements */
if (!(f_ptr->next->next))
{
first = head;
second = s_ptr->next;
s_ptr->next = NULL;
/* Reverse the second half */
second = reverse_list(&second);
/* Compare the first & second half */
ret = are_identical(first, second);
/* Finally, construct the original list back */
second = reverse_list(&second);
s_ptr->next = second;
print_list(head);
}
/* List with odd number of elements */
if (!(f_ptr->next))
{
first = head;
second = s_ptr->next;
prev->next = NULL;
s_ptr->next = NULL;
/* Reverse the second half */
second = reverse_list(&second);
/* Compare the first & second half */
ret = are_identical(first, second);
/* Finally, construct the original list back */
second = reverse_list(&second);
prev->next = s_ptr; s_ptr->next = second;
print_list(head);
}
return ret;
}
有人可以帮我弄清楚我在处理奇数案件时做错了什么吗?可以找到此程序的完整实现 here.
感谢 s7amuser 指出错误。以下是适用于偶数和奇数情况的实现。
/*
* @brief Checks if a list is a palindrome or not
*/
bool is_palindrome(node *head)
{
node *first; /* Points to head node of 1st half */
node *second; /* Points to head node of 2nd half */
node *f_ptr = head; /* Fast pointer */
node *s_ptr = head; /* Slow pointer */
node *prev = NULL; /* Previous to slow pointer */
bool ret = false; /* Return value */
while (f_ptr && f_ptr->next && f_ptr->next->next)
{
prev = s_ptr;
s_ptr = s_ptr->next;
f_ptr = f_ptr->next->next;
}
/* List with odd number of elements */
if (!(f_ptr->next))
{
first = head;
second = s_ptr->next;
prev->next = NULL;
s_ptr->next = NULL;
/* Reverse the second half */
second = reverse_list(&second);
/* Compare the first & second half */
ret = are_identical(first, second);
/* Finally, construct the original list back */
second = reverse_list(&second);
prev->next = s_ptr; s_ptr->next = second;
print_list(head);
}
/* List with even number of elements */
else if (!(f_ptr->next->next))
{
first = head;
second = s_ptr->next;
s_ptr->next = NULL;
/* Reverse the second half */
second = reverse_list(&second);
/* Compare the first & second half */
ret = are_identical(first, second);
/* Finally, construct the original list back */
second = reverse_list(&second);
s_ptr->next = second;
print_list(head);
}
return ret;
}