How to remove children from tree node list - algorithm

I have list of tree nodes. lets say (a b c d). b node is a parent of some e node and e is a parent of c. I want to write algorithm to remove nodes like c from list.
Any suggestions except iterating over all parents of each node and comparing with each element?

Related

AVL TREE traversal in order

Can someone help me, how I could traversal a balanced binary tree in order without recursion, stack, or morris traversal. I want to traverse it iteratively without modifying the tree.
Thank you so much.
In the case where there are no duplicate keys, this corresponds to the tree representing a set (or map.) In that case, a backtracking approach will be O(log n) (AVL tree property) per key. One could get a faster run time by storing the nodes, (such as in recursion,) but often this is unfeasible.
If current is not null, descend next with the current key as the target. Whenever the left is taken, first assign an ancestor (before descending.)
There are three cases: current was null -> next = root; current == next has a right child, next <- next.right; or next does not have a right child, next <- ancestor (if it does not exist, finished.)
In the first two cases, descend on the left until you hit a leaf.
I'll use Wikipedia AVL Tree article example, without the balance factors, (this will work on any binary tree, but one is not guaranteed performance.)
current
path
result
null
root J
C
C
ancestor D
D
D
ancestor F
F
F
right G
G
G
ancestor J
J
J
right P
N
N
ancestor L
L
L
ancestor P
P
P
right V
Q
Q
ancestor S
S
S
right U
U
U
ancestor V
V
V
right X
X
X
ancestor null
null
If the tree can have duplicate entries, this might be said to be a multiset. In this case, this will not work because this relies on the keys being unique.

Finding all subtrees of n-ary tree

I am trying to find all subtrees of n-ary tree. Only BFS or DFS does not work. Because the tree is not binary. For example:
1
/ \
2 3
/ \ /|\
4 6 5 7 8
/ \
9 10
I want to show all subtrees including this one
1
/ \
2 3
\ |
6 7
How can I extract this subtree from original one?
To generate all (graph-theoretic) subtrees of a given tree, I will need some auxiliary notions.
A subtree is a connected subgraph pf a tree, or equivalently, a subgraph which is also a tree.
A descendant tree of a rooted tree is either the original rooted tree itself, or a rooted tree which is a child of one of its vertices. (Won't give an exact definition here as it should be clear from the notion of a tree as a recursive data structure).
A rooted subtree of a rooted tree is a subtree that has the same root as the original rooted tree. We can get a rooted subtree of a rooted tree by computing rooted subtrees of (some of) immediate children of the root, and combining those with the original root.
Note that an arbitrary subtree is a rooted subtree of a descendant tree.
I will deal with non-empty trees for simplicity.
-- a (rooted) tree is a root node and a list of children attached to it
data Tree a = Node a [Tree a] deriving Show
It is straightforward to get the descendants:
-- a descendant tree is either a tree itself,
-- or a descendant of a child of its root
descendants :: Tree a -> [Tree a]
descendants t#(Node a ts) = t : concatMap descendants ts
Rooted subtrees are not much harder:
-- to get a rooted subtree, take a root, choose which children to
-- retain, take a rooted subtree of each retained child,
-- and attach the results to a copy of the root
rootedSubtrees :: Tree a -> [Tree a]
rootedSubtrees (Node a ts) = [Node a tts |
tts <- choices (map rootedSubtrees ts)]
-- this function receives a list of lists and generates all lists that
-- contain 0 or 1 element from each input list
-- for ex. choices ["ab", "cd"] = ["","c","d","a","ac","ad","b","bc","bd"]
choices :: [[a]] -> [[a]]
choices [] = [[]]
choices (xs:xxs) = cs ++ [x:c | x <- xs, c <- cs] where cs = choices xxs
Finally, the list of arbitrary subtrees is
subtrees :: Tree a -> [Tree a]
subtrees t = concatMap rootedSubtrees (descendants t)
You could do the following.
For each vertex in the tree you decide whether to cut the subtree with root the vertex or to keep exploring. Your number of choices is ~2^(number of nodes). Note it is note exactly 2^(number of nodes) (it's less but still exponential) since after you cut a subtree you don't explore it.
For each configuration of choices for each vertex print the tree using DFS.
Your example is the configuration in which the subtree with roots 4, 5, 8 were cut.
The cuts could be done implicitly by having flags for each node.

How does Direct branching or leaf nodes (dbl) function in Tjfast algorithm work?

I read an algorithm about Twig Pattern Matching as TJfast algorithm.
there is a function as dbl(n) ,the parameter n is a node and this function returns direct Branching or leaf Nodes but I can not understand that , the name of article is " From region encoding to extended dewey: On efficient processing of XML twig pattern matching " there is an example but is vague for me.
Base on definition in the article :
dbl(v) (for direct branching or
leaf node) returns the set of all branching nodes b and leaf nodes f in the twig
rooted at v such that there is no branching nodes along the path from v to b or
f, excluding v, b or f.
example :
dbl(a)={b,c}
dbl(c)={f,g}
I can not understand why dbl(c)={f,g} ??
dbl (directBranchingOrLeafNodes) only contains branching nodes and leaf nodes. Among those nodes, it only contains ones in which there is no intermediate branching node between them and the root.
It's surprisingly hard to find the definition for a branching node, but it appears to be a node that has more than one child. d and e are not branching nodes, because they only have one child. Therefore, they cannot be part of dbl(c).
Then, the path from c to f has no branching nodes, so f is in dbl(c). Likewise, the path from c to g has no branching nodes, so g is in dbl(c).
So we have:
dbl(c) = {f,g}
I'm guessing they probably use dbl to represent subqueries.
dbl(a) = {b,c}, because b is a leaf node and c is a branching node and both of them are descendants of a. In addition, note that there are no other branching node or leaf node which are a descendant of a and an ancestor of b( or c).
dbl(c) = {f,g}, because f and g are leaf nodes and both of them are descendants of c. In addition, note that there are no other branching node or leaf node which are a descendant of c and an ancestor of f(g).

Descendent / Ancestor query

I already looked at my book many times, but I'm confused about one definition. In my data structures and algorithms book, I have the following definition:
A node u is an ancestor of a node v if u = v or u is an ancestor of the parent of v. Conversely, we say that a node is a descendent of a node u if u is an ancestor of v.
What is the first part of the definition saying? Does it mean that a node only has two ancestors, itself (u = v) and the parent of it's parent (the parent of v)?
A node u is an ancestor of a node v if u = v or u is an ancestor of the parent of v.
This is a recursive definition, and means that the ancestors of a node are the node itself together with the node's parent and all the parent's ancestors.
The fact that the parent's ancestors are defined by the same definition is what makes it recursive, and what makes, for example, the parent's parent also an ancestor.
Perhaps a walk-through of a structure applying this definition will help.
Consider the tree:
A
/ \
B C
/ / \
D E F
/
G
If we want to find all ancestors of node G, we apply the definition:
G itself is an ancestor, and as E is G's parent, all of E's ancestors are also ancestors of G.
This means in order to find all ancestors of G we must find all ancestors of E.
Again, by the definition E itself is an ancestor of E and therefore also of G, as are all ancestors of E's parent, C.
So we have to find all ancestors of C!
Again applying the definition, C is an ancestor of itself, and thus of both E and G. And the ancestors of C's parent A are as well.
So we have to find all ancestors of A!
Well, by the definition A is its own ancestor, and as it has no parent, it has no other ancestors.
So then, having reached a terminating condition, the recursion sends us back through the stack for the result ...
C has the ancestors C (itself) and A (all the parent A's ancestors).
E has the ancestors E (itself) and C, A (all the parent C's ancestors).
*G has the ancestors G (itself) and E, C, A (all the parent E's ancestors).
I hope this makes it more clear, but, as they say, "In order to understand recursion, you must first understand recursion."

tree algorithm to do calulation on leaves and get the value to the root ,python

I have a tree and I want to loop over all nodes to give them a value (score) :
leaves nodes: the value is given by doing calculation based on the attributes of the node itself and of it sisters (calculations can be made only on leaves nodes)
non leaf nodes: they take their score from children i.e compare score of children which are leaves and get the highest one for example
I could figure out the tree traversal but I'm kind of blocked how to affect scores based on the conditions listed previously.
input tree:
((((a:1,((b:1,c:1)d:1,e:1)f:1)g:1,h:1,i:1)j:1,(k:1,l:1)m:1,(n:1,o:1,p:1)q:1)r:1)root;
traversing code:
def trav_tree(n):
if not n.is_leaf():
trav_tree(n.get_children()[0])
sisters=[]
sisters=n.get_sisters()
print n.name,
for sis in sisters:
if not sis.is_leaf():
trav_tree(sis.get_children()[0])
print sis.name,
n=t.get_tree_root()
trav_tree(n)
Output:
a b c d e f g h i j k l m n o p q r root
What I should do exactly is to calculate when I arrive to a I get the sisters I keep go down till leaves, calculate score of b and c than I take the highest score and give to d and then I can calculate the score of a and so on ...
What is the best way to solve this ?
ps: I'm working on python ete2 for Tree Data Structure
Many thanks in advance
Just add one attribute field to denote the highest score of its children for each none leaf node.
Then perform post-root traversal.

Resources