简体   繁体   English

对一段可递归检查链接列表是否为回文的代码感到好奇

[英]Curious about a piece of code that recursively checks if a link list is palindrome

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);
}

look, when the left pointer and right pointer meet at the middle of the list in case when the link list contains odd no. 看起来,当链接列表包含奇数时,当左指针和右指针在列表的中间相遇时。 of nodes, can't we terminate the recurrence faster by setting a flag equal to true if the cross- over between left and right pointers has already happened and then if the flag is true, we can directly return true without having to go through all those case checks?? 的节点,如果已经发生左右指针之间的交叉,我们是否不能通过将标志设置为true来更快地终止重复,然后如果标志为true,我们可以直接返回true,而不必遍历所有那些案件检查??

@m ohem , my question was whether we could short circuit the process of returning true when the pointers have crossed over by making them set a global flag to true once the cross-over occurs..this short circuits the recursion without having to use the jmp operation that you suggested @m ohem,我的问题是,如果指针发生交叉,是否可以通过使指针将全局标志设置为true来缩短返回指针为true的过程呢。这可以缩短递归而不必使用您建议的jmp操作

Your function is recursive. 您的函数是递归的。 It first recurses to the end of the list, such that left is at the list's head and right is at its tail. 它首先递归到列表的末尾,以使left在列表的顶部, right在列表的尾部。 When it returns fom the recursion, it does the actual palindrome checking. 当它从递归返回时,它将进行实际回文检查。 The value of right walks backwards as the recursin unwinds and left walks forwards. 当递归递减时, right的值向后走,而left向前走。 This has to happen via a pointer reference, so that other instances of the recursive functions see the change. 这必须通过指针引用进行,以便递归函数的其他实例可以看到更改。

The recursion provides a stack for the previous values of right , because your singly-linked list can't walk backwards without keeping track of where it's been. 递归为right的先前值提供了一个堆栈,因为单链接列表在不跟踪其位置的情况下无法向后移动。

Now about your question. 现在关于您的问题。 You are basically right: It does not make sense to check the letters twice. 您基本上是正确的:两次检查字母没有任何意义。 But the recursion has gone all the way up; 但是递归已经完全结束了。 it also has to go all the way down. 它也必须一直下降。 It can short-circuit the test once one of the tests is false (although it still has to pass the false value down until isPalindrome is reached), but if the word is a palindrome, everything is checked twice. 一旦其中一项测试为假,它就可以使测试短路(尽管它仍然必须传递false值直到达到isPalindrome为止),但是如果单词是回文,则将所有内容检查两次。

If you are feeling bold, you can try to jump out of the recursion with longjmp and setjmp , but you probably don't want that. 如果您感到胆怯,可以尝试使用longjmpsetjmp跳出递归,但您可能不希望这样做。 What you want is a doubly-linked list that you can traverse in opposite directions in a loop. 您需要的是一个双向链接列表,您可以在循环中以相反的方向遍历。 If your two pointers cross, just break out of the loop. 如果您的两个指针交叉,则跳出循环。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM