bool isPalindromeUtil(struct node **left, struct node *right)
{
/* stop recursion when right becomes NULL */
if (right == NULL)
return true;
/* If sub-list is not palindrome then no need to
check for current left and right, return false */
bool isp = isPalindromeUtil(left, right->next);
if (isp == false)
return false;
/* Check values at current left and right */
bool isp1 = (right->data == (*left)->data);
/* Move left to next node */
*left = (*left)->next;
return isp1;
}
// A wrapper over isPalindromeUtil()
bool isPalindrome(struct node *head)
{
isPalindromeUtil(&head, head);
}
看看,当链接列表包含奇数no时,左指针和右指针在列表中间相遇。如果左右指针之间的交叉已经发生,那么我们不能通过设置一个等于true的标志来更快地终止重复,如果标志为真,我们可以直接返回true而不必通过所有那些案件检查??
@m ohem,我的问题是,一旦发生交叉,我们是否可以通过使指针设置为true的全局标志来短路返回true的过程。这使得递归短路而没有使用你建议的jmp操作答案 0 :(得分:1)
您的函数是递归的。它首先递归到列表的末尾,这样left
位于列表的头部,right
位于其尾部。当它从递归返回时,它会进行实际的回文检查。随着递归展开而right
向前走,left
的值会向后走。这必须通过指针引用发生,以便递归函数的其他实例看到更改。
递归为先前的right
值提供了一个堆栈,因为你的单链表不能跟踪它的位置,而不能跟踪它的位置。
现在谈谈你的问题。你基本上是对的:检查字母两次是没有意义的。但递归已经一路走来;它也必须一路走下去。一旦其中一个测试结果为假,它就会使测试短路(尽管它仍然必须向下传递false
值,直到达到isPalindrome
为止,但如果这个词是回文,则检查所有内容两次。
如果您感觉很大胆,可以尝试使用longjmp
和setjmp
跳出递归,但您可能不希望这样。你想要的是一个双向链表,你可以在一个循环中以相反的方向遍历。如果你的两个指针交叉,只需突破循环。