【问题标题】:Constructing full binary tree given only postorder?仅给定后序构造完整的二叉树?
【发布时间】:2019-07-25 02:25:11
【问题描述】:

我正在尝试构建一个完整的二叉树(完全意味着每个非叶节点都有两个叶节点连接到它,即node->rightnode->left!= NULL)只考虑树的后序遍历.另外,给出后序遍历中的节点是否为叶节点。给定的后序遍历如下所示:

2(1.000000e+00)
3(1.000000e+00)
(1.000000e+00 1.000000e+00)
1(1.000000e+00)
(1.000000e+00 2.000000e+00)

例如,格式为"%d(%le)" 的行是叶节点,"(%le %le)" 是非叶节点。通常你不能只使用后序来构造树,因为连接会有多种可能性,但我确信能够区分叶节点和非叶节点在某种程度上很重要。我当前的函数如下所示:

Node *constructTreeHelper(FILE *infile, int *index) { 
    // Base case 
    if (*index <= 0) {
        return NULL; 
    }
    Node *root = NULL;

    // Check for the "(" character
    int check;
    check = getc(infile);
    fseek(infile, -1, SEEK_CUR);

    // If the node is not a leaf node
    if (check == 40) {
        double lwire, rwire;
        fscanf(infile, "(%le %le)\n", &lwire, &rwire);
        root = createNode(0, 0, lwire, rwire);
        *index = *index - 1;
        if (*index >= 0) { 
            root->right = constructTreeHelper(infile, index); 
            root->left = constructTreeHelper(infile, index); 
        } 
    } else {
        // If the node is a leaf node
        int sink;
        double cap;
        fscanf(infile, "%d(%le)\n", &sink, &cap);
        root = createNode(sink, cap, 0, 0);
        *index = *index - 1;
        if (*index >= 0) { 
            root->right = constructTreeHelper(infile, index); 
            root->left = constructTreeHelper(infile, index); 
        } 
    }
    return root;
} 

其中index 等于树中的节点数 - 1。显然,此实现仅在右侧构建节点。如何更新它以正确构建树?

编辑:让我添加一些关于我所知道的更多信息。因此,第一个节点总是必须是叶节点,而最后一个节点总是必须是根节点。由于这不是二叉搜索树,而只是一棵二叉树,因此您不能每次都使用更新的范围参数递归调用该函数。我的实现应该在 O(n) 时间内解决它,但我只是不知道如何在构建树时利用节点是否为叶节点的知识。

【问题讨论】:

    标签: c binary-tree postorder


    【解决方案1】:

    你的代码有一些问题:

    • 您应该使用ungetc() 而不是fseek() 回溯一个字符,以避免在不支持搜索的流上失败。

    • 你应该写(check == '(')而不是硬编码ASCII字符值。它更便携,更易读。

    • 为避免未定义的行为,您应该检查 EOFfscanf() 是否解析成功。事实上,这样可以避免在check 上进行测试。

    • 解析叶节点时,不应递归并解析当前节点下方的其他节点。

    • index 似乎是多余的,因为节点序列应该足以完全确定在哪里停止。

    这是修改后的版本:

    Node *constructTreeHelper(FILE *infile, int *index) { 
        double lwire, rwire;
        int sink;
        double cap;
        Node *node;
    
        // Base case 
        if (*index <= 0) {
            // This test seems redundant with the file contents */
            return NULL; 
        }
    
        // this fscanf will fail on the byte byte if it is not a '('
        if (fscanf(infile, " (%le %le)", &lwire, &rwire) == 2) {
           // If the node is not a leaf node
            node = createNode(0, 0, lwire, rwire);
            *index -= 1;
            node->right = constructTreeHelper(infile, index); 
            node->left = constructTreeHelper(infile, index); 
        } else if (fscanf(infile, "%d(%le)\n", &sink, &cap) == 2) {
            // If the node is a leaf node
            node = createNode(sink, cap, 0, 0);
            *index -= 1;
        } else {
            // invalid format or end of file */
            node = NULL;
        }
        return node;
    } 
    

    【讨论】:

    • 感谢您的更正。您在解析叶节点时不要再次调用该函数的提示很有意义。我需要找到一种方法来重写我的函数,以便它在解析叶节点后可以继续。
    • 查看我刚刚发布的代码,并尝试删除index 变量。您可以扩展语法以获得更通用的解析器,该解析器将识别 null 的不完整树。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-30
    • 2017-06-17
    相关资源
    最近更新 更多