【层次遍历】Populating Next Right Pointers in Each Node

本文介绍了使用递归和层次遍历两种方法解决完全二叉树节点连接问题的代码实现。通过递归函数setNext处理节点连接,并采用队列实现层次遍历,确保每层节点正确连接,特别关注边界条件处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这个我自己一次性AC了,因为是完全二叉树,比较好讨论,用递归来做的。

AC代码:

/**
 * Definition for binary tree with next pointer.
 * struct TreeLinkNode {
 *  int val;
 *  TreeLinkNode *left, *right, *next;
 *  TreeLinkNode(int x) : val(x), left(NULL), right(NULL), next(NULL) {}
 * };
 */
class Solution {
public:
    void setNext(TreeLinkNode *h, int isLeft, TreeLinkNode *pre)
    {
        if(isLeft==1)
            h->next=pre->right;
        else
        {
            if(pre==NULL)
                h->next=NULL;
            else
                h->next=pre->left;
        }
        //对它下面的结点进行递归
        if(h->left==NULL && h->right==NULL)
            return;
        else
        {
            setNext(h->left,1,h);
            setNext(h->right,0,h->next);
        }
    }
    
    void connect(TreeLinkNode *root) {
        //思路:setNext(h,isleft,pre) //isleft=1则为左,传入共同根节点指向pre->right;
                                     //isleft=0则为右,传入根节点->next指向next->left,若pre为空则指向空
        if(root==NULL)
            return;
        if(root->left==NULL && root->right==NULL)
            return;
        setNext(root->left,1,root);
        setNext(root->right,0,NULL);
    }
};


 

Populating Next Right Pointers in Each Node II

大致思路:

想在第一问的代码基础上进行进一步的情况讨论(传了root和root->next两个指针,分别判空分别处理),但出现了“递归过多+超时”的问题。

看题解恍然大悟,这就是层次遍历!对每一层的结点进行连接。用队列实现。

但是有个判断条件很磨人,我刚开始以为:q.size()==0就表示结点到达了该层的最右边缘,设其next=NULL。但是没考虑好的点在于:我在对该层的每个点进行处理的时候,设置next之后还需要将其的孩子入队,所以你该层的最右边缘的结点并不会一定满足“队列为空”

那怎么样可以判断,该层到达了最右边缘呢?

思路是,在每进入一层时,该层的结点都已经全部入队了,所以此时先求队的长度len=q.size(),以len次的for循环来处理len个结点,这len个结点都是这一层的,直到i==len-1则说明该层的最后一个结点即最右边缘的结点,设其->next=NULL。

AC代码:

/**
 * Definition for binary tree with next pointer.
 * struct TreeLinkNode {
 *  int val;
 *  TreeLinkNode *left, *right, *next;
 *  TreeLinkNode(int x) : val(x), left(NULL), right(NULL), next(NULL) {}
 * };
 */
class Solution {
public:
    void connect(TreeLinkNode *root) {
        if(root==NULL)
            return;
        if(root->left==NULL && root->right==NULL)
            return;
        //层次遍历的思想,用队来存储
        queue<TreeLinkNode*>q;
        q.push(root);
        while(q.size()!=0)
        {
            int len = q.size();  //这里先取长度,然后一个for循环把该层的结点都处理了
            for(int i=0;i<len;i++) //len次 
            {
                TreeLinkNode* p = q.front();
                q.pop();
                //先解决自己的next问题
                if(i==len-1)  //这里没一次性写对。有可能有孩子,但该结点仍在右边缘!
                    p->next=NULL;
                else
                    p->next=q.front();
                
                //再入队自己的孩子
                if(p->left!=NULL)
                    q.push(p->left);
                if(p->right!=NULL)
                    q.push(p->right);
            }
            
        }
    }
};


 

### 如何设置数据库模式并填充表格中的数据 为了帮助理解如何创建数据库模式并向表中插入数据,以下是基于提供的引用和其他专业知识的内容。 #### 创建数据库模式 在关系型数据库管理系统(RDBMS)中,创建数据库模式通常涉及定义表结构及其之间的关系。以下是一个简单的例子: ```sql CREATE TABLE Users ( UserID INT PRIMARY KEY, UserName VARCHAR(50), Email VARCHAR(100) ); CREATE TABLE Orders ( OrderID INT PRIMARY KEY, UserID INT, Amount DECIMAL(10, 2), FOREIGN KEY (UserID) REFERENCES Users(UserID) ); ``` 上述代码片段展示了两个表 `Users` 和 `Orders` 的创建过程[^1]。通过这种方式可以确保数据模型满足业务需求,并建立必要的约束条件来维护数据一致性。 如果使用的是 MongoDB 这样的 NoSQL 数据库,则可以通过编程语言实现类似的逻辑操作。例如,在 Java 中利用 Spring Data MongoDB 提供的功能快速完成初始化工作: ```java import org.springframework.data.mongodb.core.MongoTemplate; import com.mongodb.client.MongoClient; public class DatabaseSetup { public static void main(String[] args) { MongoClient mongoClient = ...; // Initialize client here. String dbName = "exampleDatabase"; MongoTemplate mongoTemplate = new MongoTemplate(mongoClient, dbName); // Example document insertion logic goes below this point... } } ``` 此段程序演示了怎样借助于 Spring Framework 下的工具类 `MongoTemplate` 来连接指定名称的数据存储实例[^2]。 #### 填充测试数据到已存在的表里去 当确认好架构之后就需要考虑怎么把实际的信息填进去。对于传统的关系型数据库而言,这一步骤可能涉及到执行批量 INSERT INTO 查询语句或者导入 CSV 文件等形式;而对于文档导向型非关系型数据库来说则可能是序列化对象再保存的过程。 假设我们已经有了上面提到过的两张表 (`Users`, `Orders`) ,那么现在就可以尝试往里面加入几条记录作为样例展示用途: ```sql INSERT INTO Users VALUES (1,'John Doe','john@example.com'), (2,'Jane Smith','jane@example.org'); INSERT INTO Orders VALUES (101,1,99.99),(102,2,45.67); ``` 这些命令将会分别向各自的对应位置写入新成员以及关联订单详情。 另外值得注意的一点是在某些情况下还需要提交事务才能让更改永久生效。比如当你正在使用 Oracle 数据库并通过其命令行界面(SQL*Plus)来进行管理的时候就应当记得发出 COMMIT 指令: ```bash COMMIT; ``` 最后提醒一下开发者们务必仔细阅读官方发布的更新日志文件以便及时了解到最新的改动之处从而调整自己的项目配置使之兼容最新版本特性[^3]。 #### 使用高级框架简化流程 现代开发环境中往往倾向于采用更高效的解决方案减少重复劳动量提高生产力水平。RestKit 就是这样一个用于 iOS 平台上的开源库它能够自动处理来自远程服务器端口返回来的 JSON 格式的响应消息转换成本地 CoreData 实体模型而无需手动解析每一个字段逐一赋值给属性变量等等繁琐步骤[^4]. 虽然这里讨论的主题主要围绕着后端部分但是前端同样存在许多优秀的第三方插件可以帮助加速整个应用程序构建周期因此建议大家多加探索学习不同技术栈的知识体系综合运用起来解决问题更加高效便捷。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值