algorithmtreebinary-treeinorderpostorder

Given an inorder threaded binary tree and a node, how to find the parent of that particular node?


The image in the link below is an example of a INORDER THREADED BINARY TREE

We're given a binary tree with inorder threads. Meaning, if a node does not have a left child (right child), left threads (right threads) are linked from that node to its inorder predecessor (inorder successor).

Can you help me come up with pseudocode or algorithm that would find a node's parent? For example (see photo below), the given node is Q, the parent must be I. (We are supposed to make use of the given idea that the binary is inorder threaded)

TMI: I actually need this pseudocode/algorithm in creating another algorithm that would get the postorder successor of a binary tree.


Solution

  • From the picture it seems that:

    Then the logic for finding the parent of a given node can be as follows:

    Here is an implementation of that idea in JavaScript. This code snippet defines a Node class. It creates the tree given in the example. The Node class has an inorder iterator which we use to visit each node and then display its parent using the above algorithm:

    class Node {
        constructor(value=null, left=null, right=null) {
            this.value = value;
            this.hasLeft = false;
            this.hasRight = false;
            this.left = left || this; // Default is self-reference
            this.right = right || this; // Default is self-reference
        }
        insertLeft(value) {
            this.hasLeft = true;
            this.left = new Node(value, this.left, this);
            return this.left;
        }
        insertRight(value) {
            this.hasRight = true;
            this.right = new Node(value, this, this.right);
            return this.right;
        }
        parent() {
            // Find rightmost node of subtree
            let node = this;
            while (node.hasRight) {
                node = node.right;
            }
            node = node.right; // go to ancestor
            // The this-node is in the left subtree of node.
            if (node.left === this) return node;
            node = node.left;
            while (node.right !== this) {
                node = node.right;
            }
            return node;
        }
        * inorder() {
            if (this.hasLeft) yield * this.left.inorder();
            if (this.right !== this) yield this; // When it is not the head
            if (this.hasRight) yield * this.right.inorder();
        }
    }
    
    // Create the example tree:
    let head = new Node(); // Sentinel node (without data)
    head.insertLeft("C").insertLeft("I").insertLeft("Q").insertRight("U").right.right
                        .insertRight("S").insertLeft("K").right
                                         .insertRight("R").insertLeft("O").right
                                                          .insertRight("T");
    
    // Visit each node, display its value and that of its parent:
    for (let node of head.inorder()) {
        console.log("parent of " + node.value + " is " + node.parent().value);
    }