简体   繁体   中英

Constructing full binary tree given only postorder?

I'm trying to construct a full binary tree (full meaning that every non leaf node has two leaf nodes connecting to it, ie node->right and node->left are != NULL ) given only the postorder traversal of the tree. In addition, I am given whether or not the node in the postorder traversal is a leaf node or not. The given postorder traversal looks like this:

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

for example, where a line of the format "%d(%le)" is a leaf node and "(%le %le)" is a non-leaf node. Normally you can't construct a tree using only postorder because there would be multiple possibilities for connections, but I'm sure that being able to differentiate leaf vs. non-leaf nodes is important somehow. My current function looks like this:

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;
} 

where index is equal to the number of nodes in the tree - 1. Obviously, this implementation only builds nodes to the right. How can I update this to properly construct the tree?

Edit: Let me add some more information about what I know. So, the first node always has to be a leaf node, and the last node always has to be the root. Since this is not a binary search tree, but rather simply a binary tree, you cannot recursively call the function with updated range parameters each time. My implementation should solve it in O(n) time, but I just can't figure out how to make use of the knowledge in whether or not a node is a leaf node in constructing the tree.

There are some problems in your code:

  • you should use ungetc() instead of fseek() to backtrack by one character to avoid failure on streams that do not support seeking.

  • you should write (check == '(') instead of hard coding the ASCII character value. It is both more portable and more readable.

  • To avoid undefined behavior, you should check for EOF and for fscanf() parsing success. As a matter of fact, this would avoid the need for the test on check .

  • When you parse a leaf node, you should not recurse and parse further nodes below the current one.

  • index seems redundant as the sequence of nodes should suffice to full determine where to stop.

Here is a modified version:

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;
} 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM