构造仅给定后序的完整二叉树?

时间:2019-03-03 18:03:04

标签: c binary-tree postorder

我正在尝试构建一个完整的二叉树(完全意味着每个非叶节点都有两个与其连接的叶节点,即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)时间内解决它,但我只是想不通如何在构造树时利用节点是否为叶节点的知识。

1 个答案:

答案 0 :(得分:2)

您的代码中存在一些问题:

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

  • 您应该写fseek()而不是硬编码ASCII字符值。它既便携又可读。

  • 为避免未定义的行为,应检查(check == '(')EOF的解析成功。实际上,这样可以避免对fscanf()进行测试。

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

  • check似乎是多余的,因为节点顺序应足以确定停在哪里。

这是修改后的版本:

index