1028. 从先序遍历还原二叉树

本文介绍了一种通过深度优先搜索(DFS)遍历字符串来还原二叉树的方法。通过对遍历字符串的解析,可以确定每个节点的深度及其值,从而重建原始的二叉树结构。文章提供了具体的代码实现,展示了如何从给定的遍历输出中恢复树的根节点。
摘要由CSDN通过智能技术生成

我们从二叉树的根节点 root 开始进行深度优先搜索。

在遍历中的每个节点处,我们输出 D 条短划线(其中 D 是该节点的深度),然后输出该节点的值。(如果节点的深度为 D,则其直接子节点的深度为 D + 1。根节点的深度为 0)。

如果节点只有一个子节点,那么保证该子节点为左子节点。

给出遍历输出 S,还原树并返回其根节点 root。

示例 :

输入:"1-2--3--4-5--6--7"
输出:[1,2,5,3,4,6,7]



输入:"1-2--3---4-5--6---7"
输出:[1,2,5,3,null,6,null,4,null,7]
输入:"1-401--349---90--88"
输出:[1,401,null,349,88,90]

提示:

原始树中的节点数介于 1 和 1000 之间。
每个节点的值介于 1 和 10 ^ 9 之间。

代码:

/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
func recoverFromPreorder(S string) *TreeNode {
    root := []*TreeNode{}
    index := 0
    for index < len(S) {
        // 获取节点level
        level := 0
        for S[index] == '-'{
            level++
            index++
        }
        // 获取值
        sValue := ""
        for index < len(S) && S[index] >= '0' && S[index] <= '9' {
            sValue += string(S[index])
            index++
        }
        value,_ := strconv.Atoi(sValue)
        node := &TreeNode{Val: value}
        // 找节点
        if level == len(root){ // 左节点,一路遍历到底
            if len(root) > 0 {
                root[len(root) - 1].Left = node
            }
        } else { // 一直到level不是下一个子节点
            // 直接截取到对等level的子节点,赋予右节点
            root = root[:level]
            root[len(root) - 1].Right = node
        }
        root = append(root, node)
    }
    return root[0]
}
下面是用 C++ 实现拓展先序遍历还原二叉树的代码: ```cpp #include <iostream> #include <string> using namespace std; struct TreeNode { int val; TreeNode* left; TreeNode* right; TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} }; TreeNode* buildTree(string& s, int& index) { if (index >= s.size() || s[index] == '#') { return nullptr; } int val = s[index] - '0'; TreeNode* root = new TreeNode(val); index++; root->left = buildTree(s, index); index++; root->right = buildTree(s, index); return root; } void inorderTraversal(TreeNode* root) { if (root == nullptr) { return; } inorderTraversal(root->left); cout << root->val << " "; inorderTraversal(root->right); } int main() { string s = "123##4##56##"; int index = 0; TreeNode* root = buildTree(s, index); inorderTraversal(root); cout << endl; return 0; } ``` 以上代码中,我们首先定义了一个 TreeNode 结构体,用于表示二叉树节点信息。我们还定义了一个 buildTree 函数,用于构建二叉树。该函数以拓展先序遍历序列作为输入,同时还维护了一个 index 变量,用于表示当前处理的字符下标。函数返回构建好的原二叉树的根节点。 具体地,我们首先判断当前字符是否为 '#',如果是则返回空节点。接着,我们从输入序列中获取当前节点的值,构建当前节点,并递归处理其左右子树。最终,我们返回构建好的原二叉树的根节点。 在 main 函数中,我们定义了一个拓展先序遍历序列作为输入,然后调用 buildTree 函数构建原二叉树,并采用中序遍历的方式输出二叉树节点的值,以验证还原结果是否正确。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值