递归条件一定要严谨



在牛客网上写LEETCODE,写到这个题

Given a binary tree

    struct TreeLinkNode {
      TreeLinkNode *left;
      TreeLinkNode *right;
      TreeLinkNode *next;
    }


Populate each next pointer to point to its next right node. If there is no next right node, the next pointer should be set toNULL.

Initially, all next pointers are set toNULL.

Note:

  • You may only use constant extra space.
  • You may assume that it is a perfect binary tree (ie, all leaves are at the same level, and every parent has two children).


For example,
Given the following perfect binary tree,

         1
       /  \
      2    3
     / \  / \
    4  5  6  7


After calling your function, the tree should look like:

         1 -> NULL
       /  \
      2 -> 3 -> NULL
     / \  / \
    4->5->6->7 -> NULL
想着可以用下面的代码
class Solution {
public:
    void connect(TreeLinkNode *root) {
        if (root == NULL) return;
        if (root->left!=NULL)
            root->left->next = root->right;
        if (root->next!=NULL)
            root->right->next = root->next->left;
        connect(root->left);
        connect(root->right);
    }
};
但是总是报错,错误信息为段错误,调用递归层数太多。我就很奇怪,查了下人家写的发现也都用的递归,怎么我这就不行了呢?
于是开始对比自己和别人的代码,发现人家在后两个if判断上都加了一条root->right!=NULL,那么就需要分析一下为什么要加这一句。
首先,第二个if应该是不需要加这一句的,因为题目中的条件是完全二叉树,所以如果节点没有左孩子那就一定也没有右孩子,就算加了这一句,这个判断也一定会被“与”给短路掉,所以加不加其实都一样了。
然后,第三个if确实是一定要加这一句的。我的代码无法通过就是这个原因。如果不加的话,在进行到树的最后一个节点,由于它的next指针指向NULL,所以符合条件,递归继续,而之后每一个空节点的next都是空的,都符合条件,所以就崩了,递归无限进行下去。因此,必须要让程序知道最后一个节点到了,不需要继续下去了。让程序知道这个节点到了的条件就是节点的next和right指针同时指向NULL。
因此,最终用以下的代码就过了
class Solution {
public:
    void connect(TreeLinkNode *root) {
        if (root == NULL) return;
        if (root->left!=NULL)
            root->left->next = root->right;
        if (root->next!=NULL&&root->right!=NULL)
            root->right->next = root->next->left;
        connect(root->left);
        connect(root->right);
    }
};
递归条件的考虑确实要慎之又慎。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值