检查单链接列表是否为回文列表(C)
我试图检查单链表是否是回文。约束条件是-算法必须在线性时间和恒定空间中 我使用的基本算法如下-检查单链接列表是否为回文列表(C),c,pointers,linked-list,palindrome,singly-linked-list,C,Pointers,Linked List,Palindrome,Singly Linked List,我试图检查单链表是否是回文。约束条件是-算法必须在线性时间和恒定空间中 我使用的基本算法如下- 使用快速和慢速指针将列表分成两半 将后半部分反转到位 比较上半场和下半场 重新构造原始列表 返回结果 我的实现适用于元素数为偶数的列表,但如果元素数为奇数,则会失败 /* * @brief Checks if a list is a palindrome or not */ bool is_palindrome(node *head) { node *first;
/*
* @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;
}
有人能帮我弄清楚在处理奇数案时我做错了什么吗?可以找到此程序的完整实现。感谢您指出错误。下面是适用于偶数和奇数情况的实现
/*
* @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;
}
我认为您需要重新搜索下半部分的第一个节点。它需要指向中间节点(偶数情况)或“N div 2+1”节点(奇数情况)。然后你只需旋转一半并穿过它。IMHO您不需要对奇数情况进行任何特殊处理,因为没有为此特定节点设置任何规则。您可以使用此解决方案:当您说您的实现“如果元素数为奇数则失败”时,这意味着什么?发生了什么事?程序崩溃?结果不正确?将列表的前半部分反转(您可以将列表拆分为两半)而不是反转第二部分可能会更容易一些。无论哪种方式,当列表中有奇数个元素时,正如Paul所说,中间的元素对结果都没有影响。这似乎就是你出错的地方。我假设它是错误的,但应该是因为这个
if!(f_ptr->next->next)
。如果列表中有奇数个元素,则f_ptr
将指向第一个循环完成后的最后一个元素。因此,f_ptr->next
将NULL
因此f_ptr->next->next
将发生故障。首先尝试检查!(f_ptr->next)
且仅在之后!(f_ptr->next->next)
。