I'm wondering what the consensus is on the definition of "ancestor" in a computer science context.
I only ask because in Introduction to Algorithms, Second Edition, p. 259 there is a description of the algorithm Tree-Successor(x) that seems odd. In finding the successor of node x,
[...] if the right subtree of node x is empty and x has a successor y, then y is the lowest ancestor of x whose left child is also an ancestor of x.
In a binary search tree with a root having key 2 and children 1 and 3, the successor of 1 is its parent 2. In this case, x is the left child of x's successor, y. According to the book's definition, then, x must be its own ancestor, unless I'm missing something.
I haven't found anything in the errata about this.
It's merely a matter of definition, but in this case, yes. CLRS define an ancestor of x as any node on the unique path from the root to x, which by definition includes x.
The sentence fragment you quoted begins by mentioning exercise 12.2-6 on the next page, which specifies this:
(Recall that every node is its own ancestor.)
:-)
Is a node in a tree considered its own ancestor?
Not normally, AFAIK. For example, in the Wikipedia page on binary trees, ancestor is defined thus:
If a path exists from node p to node q, where node p is closer to the root node than q, then p is an ancestor of q and q is a descendant of p.
But apparently that text book's definition of ancestor is such that a node is its own ancestor. This definition is not exactly intuitive, but a textbook is free to introduce its own definitions for the terminology that it uses. Maybe this definition simplifies some of the related descriptions / theorems / etc.
No, a node is not ancestor of itself. According to me it should be: if the right subtree of node x is empty and x has a successor y, then y is the lowest ancestor of x whose left child is either x or an ancestor of x. but the code given in the book supposedly handling such type of cases.
Related
There are many resources on the Internet for Tarjan's algorithm that finds the dominator tree with respect to a single entry node. However, I just want to find the dominators of a single node of the tree.
Is there an easier way to do this than using Tarjan's O(m log n) time algorithm which computes the dominator tree and then we iterate through the tree to find the dominators of a particular node? I want to do this quicker than O(m log n) time for the single node case.
Although I don't know of any existing algorithm that does this, I can think of one.
Let the entry node be the root, and the target node (to find its dominators) be t. Make a DFS tree rooted at root.
Now note that the set of dominators of t are a subset of the ancestors of t on the DFS tree, and only forward edges and cross edges can "avoid" those nodes on a path from root to t. So:
For each node node, let f(node) be the highest ancestor of t that can reach node without walking on any other ancestors of t. This can be computed in linear time with memoization.
For each cross edge x → y where y is an ancestor of t, all nodes that are strict sucessors of f(x) and strict ancestors of y are not dominators of t. (because the path root → ... → f(x) → ... → x → y → ... → t does not path through those nodes)
The algorithm (O(n+m)) would be:
Make a DFS tree rooted as root.
Mark all ancestors of t as "possible candidates".
Compute f(node) for all nodes.
For each x → y as described above, mark the list of nodes in the path f(x) → ... → y (excluding endpoints) as "cannot be dominators" in O(1) time using summed table. (similar to summed area table but in 1D)
The remaining candidates are dominators.
Not sure if this is easier.
Can a Binary Tree / Binary Search Tree only have the parent and one of the left or right nodes?
Or is it mandatory to have both the left and right nodes?
Binary implies two. Binary trees have two children pointers, not necessarily with references to anything. Parent references are not necessary - that is up to implementation.
If nodes were mandatory to have both children elements, then the tree would be infinite and leaves would not exist.
So, options for a node are
leaf
left/right child only
both children
Of course, there are alternative ways to think about a "tree". For example, take the binary heap array implementation.
It is not mandatory, you can create other types of links if you want. Define up and down pointers like this.
For a node x define up pointer u(x) as:
if x is the right child, then u(x) is the parent of x
if x is left child or root, then u(x) is the lowest node on the right path of x
For a node x define down pointer d(x) as:
if x's left subtree does not exist, then d(x) = x
if left subtree exists, then d(x) points to the rightmost node of x's left subtree
This is so called ring representation of a tree.
Actually, there is nothing mandatory other than just one rule (i.e. the maximum number of children that any binary tree node can have is two).
Technically:
Even a NULL is considered as a tree node when we define TreeNode *root = NULL.
Though, it has no practical significance, we do pass them as argument while calling insert, delete and display methods.
So, as a coder, assuming that a binary tree will always comprise of at least a parent node can prove fatal if the sanity of root is not checked before processing a binary tree.
A binary search tree is also a binary tree with additional properties. Any Binary tree node can have either 0 or 1 or 2 child nodes. So to answer your question, its okay to have only left or right nodes
I study CS in the university and I've got a question I'm having problem proving.
Prove that the successor Y of node X on a BST, when X doesn't have right child, is the lowest ancestor of X, that is left child is also an ancestor of X.
I need to consider all cases, including leaf, except the rightmost because he has no successor.
Can you guys give me some hints from where to start?
An inorder traversal of a BST node visits the left subtree, the node itself, and then the right subtree.
So, if X (which doesn't have a right child) is the left child of its parent, then we know that its successor is the parent. This follows from the definition of inorder traversal.
If X is the right child of its parent, then the parent precedes it in the traversal (although it's not the immediate predecessor unless X has no left subtree). This, too, follows from the definition of inorder traversal. The successor of X, since it doesn't have a right subtree, must be above it in the tree. The successor can't be the parent, so it must be what the parent's successor would be if X didn't exist.
My problem is:
Consider two trees P and R. I need to match the node at the deepest possible level of P with the node at deepest possible level of tree R. That means, all nodes in a tree are like a hierarchical relation from most general to most specific. The most specific match from tree P with tree R should be found.
The most optimal method is needed.
For example, lets have a Reviewers' panel. Each reviewer has his own tree of interests going from general interest to specific like from Energy to Biogas plant. Now there's a paper to be matched with the reviewer's interests. The reviewer with the most specific match with the paper's category is to be found. Each paper also has its category tree from most general category to exactly specific category.
EDIT: Fixed expression for depth difference
Decide how much importance you want to give to matching nodes on their depth, versus on their "similarity". Use this to make a scoring function s(x, y) = a*(-|depth(x) - depth(y)|) + (1-a)*(similarity(x, y)). (similarity(x, y) can be any function of x and y -- e.g. it might be the length of their longest common subsequence, if x and y are strings.)
(Conceptually) create a vertex for each node in tree 1, a vertex for each node in tree 2, and an edge for every pair of vertices (x, y) with x in the first tree and y in the second. Set the weight of this edge to s(x, y).
You now have a bipartite maximum weighted matching problem, a.k.a. Assignment Problem. Apply the Hungarian algorithm to find the optimal solution in O(n^3) time.
You can solve it using Trie, where the root has the most generalized categories and its children has more specific categories and their children have more and more specific. You need to find the longest matching starting from the root.
If I have a binary search tree like this then what will be lowest common ancestor of nodes 6 and 1?
According to the Wikipedia definition of the Lowest common ancestor I correct myself:
The lowest common ancestor (LCA) is a concept in graph theory and
computer science. Let T be a rooted tree with n nodes. The lowest
common ancestor is defined between two nodes v and w as the lowest
node in T that has both v and w as descendants (where we allow a node
to be a descendant of itself).
So yes going by this definition the correct answer would be 6. If this is an interview question would be good to clarify in advance with the interviewer.