Is therer such a thing as the height of a node in a BST? - binary-search-tree

I'm getting confused the more I search. Does the term "height" only apply to the root node of a BST? Or does each node have its own corresponding height? Similarly, does each node of a BST have a corresponding level?

Height of a BST or any binary tree is the total number of edges from the root node to the most distant leaf node. You are probably getting confused with recursion when a node on another level is passed as the root. For every node, it is the parent of its subtree, so it is the root for that subtree. That's how recursion works.

Related

Is it possible for a red black tree to have a node being black, node's parent being black, but the parent has no siblings?

I'm reading through red black tree chapter from the book "introduction to algorithms" by Cormen. In that delete chapter, it basically says if both the node and node's parent are black, then the sibling of node's parent has to exist. The text is in page 327 first paragraph.
I don't get the logic for it, like how do we deduct something like that? Is that even true?
Though I did try to implement my own version of RB Tree and I couldn't produce a tree with a subtree like
/
R
/
B
/ \
B ...
/
...
or
/
B
/
B
/ \
B ...
/
...
Basically both node and parent are black but parent doesn't have sibling. Can't produce it so far
The text is correct. The only time you can have a black node with no sibling is when the node in question is the tree root. The easy way to think of this is to draw out the B-tree equivalent, Moving red nodes up so they are part of the same block as their parent black node. When you do this it becomes easy to see that a non-root black node with no sibling is going to produce an unbalanced tree.
In fact the two options for a non-root non-leaf black node are that either the sibling is black, or the sibling is red and has two black children (even if those two children are leaf nodes and simply represented by a null value in the implementation).
SoronelHaetir is right. But there are 3 things to say about fixups of deletes:
When "sibling" is talked about, this is normally the sibling of the current Node. It is not usually parent's sibling. So if the current Node is the left child of the parent then the "sibling" is the right child of the parent.
You say "I don't get the logic for it, like how do we deduct something like that? Is that even true?". Yes it is. One of the rules is the total black Node count down every path is the same.
So in a correct RB tree, for a given node, if the left child is black, then the right child is black (or it is red and it has 2 black children). For a correct RB Tree, you cannot have any node with an unbalanced count of black nodes down all paths. The count has to be the same in every path.
The other situation where you have unbalanced black tree count is where a leaf node has been deleted and it is black, and you are in the process of restoring the black tree count. Until it is restored (which can always be done), the tree is not a valid RB Tree.

How would I find all paths between two nodes using cytoscape.js?

I have a telecommunications mesh network graph where there are multiple path between multiple nodes.
I want to be able to select 2 nodes and highlight all inter connected nodes and edges that make up the paths between them.
How would you recommend I tackle this?
I've tried using aStar, then removing the nodes and edges and reiterating, however some paths share edges so that didn't work.
To get all of the paths between two nodes in Cytoscape.js you can use the following:
function findPaths(src,dest) {
let successors = src.successors();
let predecessors = dest.predecessors();
return successors.intersection(predecessors);
}
This takes all of the nodes and edges from src and keeps only those that are also in the set of those leading to dest.
It does not enumerate the paths - it is just the full set of nodes and edges in the paths.
To actually enumerate all the individual possible paths (it can be a large number if you're dealing with a complex graph) you would do a depth first recursion on the results of this function. Each time dest is visited, you would display the path that led to the visit.

Binary Search Tree Minimum Value

I am new to binary search tree data structure. One thing I don't understand is why the leftest node is the smallest
10
/ \
5 12
/ \ / \
1 6 0 14
In the above instance, 0 is the smallest value not 1.
Let me know where I got mixed up.
Thank you!
That tree is not binary search tree.
Creating a binary search tree is a process which starts with adding
elements.
You can do it with array.
First there is no element so make it root.Then start adding elements as node.If the new value is bigger than before add it array[2 x n + 1] (call index of the last value: n). If it is smaller than before add it to array[2 x n]. So all values left of any node is smaller than it and all values right of any node is bigger than it. Even 10 and 6's place.6 cannot be 11.(at your tree,it isn't actually.).That's all !
For a tree to be considered as a binary search tree, it must satisfy the following property:
... the key in each node must be greater than all keys stored in the left sub-tree, and smaller than all keys in right sub-tree
Source: https://en.wikipedia.org/wiki/Binary_search_tree
The tree you posted is not a binary search tree because the root node (10) is not smaller than all keys in the right sub-tree (node 0)
I'm not really sure of your question, but binary search works by comparing the search-value to the value of the node, starting with the root node (value 10 here). If the search-value is less, it then looks at the left node of the root (value 5), otherwise it looks next at the right node (12).
It doesn't matter so much where in the tree the value is as long as the less and greater rule is followed.
In fact, you want to have trees set up like this (except for the bad 0 node), because the more balanced a tree is (number of nodes on left vs. number of nodes on right), the faster your search will be!
A tree balancing algorithm might, for example, look for the median value in a list of values and make that the value of the root node.

Binary Search Tree determining root

In a binary search tree, how do you determine which list item should be the root, and which items should be the leafs?
To make it optimized each root should be the mid point for each leaf, making the tree more balanced.

Gain maximization on trees

Consider a tree in which each node is associated with a system state and contains a sequence of actions that are performed on the system.
The root is an empty node associated with the original state of the system. The state associated with a node n is obtained by applying the sequence of actions contained in n to the original system state.
The sequence of actions of a node n is obtained by queuing a new action to the parent's sequence of actions.
Moving from a node to another (i.e., adding a new action to the sequence of actions) produces a gain, which is attached to the edge connecting the two nodes.
Some "math":
each system state S is associated with a value U(S)
the gain achieved by a node n associated with the state S cannot be greater than U(S) and smaller than 0
If n and m are nodes in the tree and n is the parent of m, U(n) - U(m) = g(n,m), i.e., the gain on the edge between n and m represents the reduction of U from n to m
See the figure for an example.
My objective is the one of finding the path in the tree that guarantees the highest gain (where the gain of a path is computed by summing all the gains of the edges on the path):
Path* = arg max_{path} (sum g(n,m), for each adjacent n,m in path)
Notice that the tree is NOT known at the beginning, and thus a solution that does not require to visit the entire tree (discarding those paths that for sure do not bring to the optimal solution) to find the optimal solution would be the best option.
NOTE: I obtained an answer here and here for a similar problem in offline mode, i.e., when the graph was known. However, in this context the tree is not known and thus algorithms such as Bellman-Ford would perform no better than a brute-fore approach (as suggested). Instead, I would like to build something that resembles backtracking without building the entire tree to find the best solution (branch and bound?).
EDIT: U(S) becomes smaller and smaller as depth increases.
As you have noticed, a branch and bound can be used to solve your problem. Just expand the nodes that seem the most promising until you find complete solutions, while keeping track of the best known solution. If a node has a U(S) lower than the best known solution during the process, just skip it. When you have no more node, you are done.
Here is an algorithm :
pending_nodes <- (root)
best_solution <- nothing
while pending_nodes is not empty
Drop the node n from pending_nodes having the highest U(n) + gain(n)
if n is a leaf
if best_solution = nothing
best_solution <- n
else if gain( best_solution ) < gain( n )
best_solution <- n
end if
else
if best_solution ≠ nothing
if U(n) + gain(n) < gain(best_solution)
stop. best_solution is the best
end if
end if
append the children of n to pending_nodes
end if
end while