好奇一段代码,递归检查链接列表是否是回文

时间:2014-05-27 07:35:06

标签: c linked-list

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操作

1 个答案:

答案 0 :(得分:1)

您的函数是递归的。它首先递归到列表的末尾,这样left位于列表的头部,right位于其尾部。当它从递归返回时,它会进行实际的回文检查。随着递归展开而right向前走,left的值会向后走。这必须通过指针引用发生,以便递归函数的其他实例看到更改。

递归为先前的right值提供了一个堆栈,因为你的单链表不能跟踪它的位置,而不能跟踪它的位置。

现在谈谈你的问题。你基本上是对的:检查字母两次是没有意义的。但递归已经一路走来;它也必须一路走下去。一旦其中一个测试结果为假,它就会使测试短路(尽管它仍然必须向下传递false值,直到达到isPalindrome为止,但如果这个词是回文,则检查所有内容两次。

如果您感觉很大胆,可以尝试使用longjmpsetjmp跳出递归,但您可能不希望这样。你想要的是一个双向链表,你可以在一个循环中以相反的方向遍历。如果你的两个指针交叉,只需突破循环。