What is post traversal of forest - algorithm

Can someone explain it in detail?(it's forest ,not binary tree)
I'm reading the tree and forest chapter of data structure book,I've known the pre order traversal and in order traversal of forest.

Post traversal is a kind of method to explore your tree or forest.
in detail, post traversal mean you will explore nodes nearest to the leaf including the leaf itself.
In action; you should always go to your first or leftmost node until the current node does not have any child. if that occurs, you do your actions with the note , go to his parent, go to "his next son" and the you keep going deep into that node repeting the process (first leftmost child, etc...).
Heres an image that can help you understand

Related

Splay Tree Deletion

I'm having trouble conceptualising the process of deletion from a splay tree. Given this intial, tree, I want to delete the node 78.
Based on the information from my course (derived from Goodrich, Tamassia and Goldwasser), the deleted node in a BST should be replaced by the next node reached by performing an in-order traversal from the node which should be 91. This node should then be splayed to the top of the tree. However, this is not the case as shown on this visualiser here. https://www.cs.usfca.edu/~galles/visualization/SplayTree.html
The visualizer replaced 78 by its in order predecessor (70) instead and splayed that node. (The in order successor, i.e., the next key in sorted order is 83, not 91.) In general, splay trees are wonderfully malleable and as long as you approximately halve the length of the path you just descended while making every other path at most a little bit longer, you’re doing it right from an asymptotic performance standpoint (your professor may have different ideas, however).
Your textbook description:
the deleted node in a BST should be replaced by the next node reached by performing an in-order traversal from the node which should be 91
That description applies to unbalanced BST (binary search trees) but does not apply to most of the various kinds of balanced binary trees, and also does not apply to Splay Trees. To delete a node in a splay tree do the following:
Splay the node to be deleted to the root and dispose of it. This leaves two trees, call the left tree A and the right tree B.
The new root of the recombined tree will come from A. Splay the largest (rightmost) node of A tree to its root.
Because A's new root has the greatest key in A, it has no right child. Set the right child of A's new root to B.
A is the new combined tree.
This is what the visualization at https://www.cs.usfca.edu/%7Egalles/visualization/SplayTree.html did.
You said in comments to the other answer:
So in practice, the node that you choose to replace the deleted node doesn't really matter, i.e. affect performance etc.
In the typical splay tree deletion algorithm the node to replace will be the predecessor or successor node, in key order.
The rule of thumb is to always splay whenever a specific node is accessed. Find the node to delete, then splay it to the root. Find its predecessor, then splay it to the root. There are variations where you can splay less aggressively, too.

Idiomatic Traversal Binary Tree (Perhaps Any Tree)

A Doubly Linked List enables idiomatic traversal of a Linked List and I thought why not for a Binary Tree? Traditionally, Binary Trees or Trees ingeneral are unidirectional and that implies, given a large tree with sufficient number of nodes, the running time to find a leaf node can be costly.
If, after finding such a node, to find the next I could traverse the tree back toward the root, would that not be advantageous as compared to another depth-first search through every node of the tree? I have never considered this before until realizing the marriage of a Doubly Linked List and a Binary Tree could potentially add benefit.
For example, if I employed an inner class
class Tree<T> {
private class TwoWayNode {
var data : T
var left : TwoWayNode
var right : TwoWayNode
var previous : TwoWayNode
}
}
The use of left and right are as normal to traverse the respective subtrees from each node and previous would hold a pointer to the parent node enable idiomatic traversal. Would someting like this work well and what are some of the potential problems or pitfalls?
Given you store a previous reference, you can walk leftmost first. Upon arrival at the leaf node, you back one up again, traverse right.
You can always compare the current node, your "walker", with the child nodes, so you can check if you went left or right the last time. This makes your traversal stateless and you do not even need recursion; suitable for very large datasets.
Now, everytime you just left the right leaf, you back one up again.
This algorithm is a Depth-First-Search.*
Making it faster:
Given that you could define some deterministic condition for the order of traversal, this can become quite flexible, and even be used in applications like ray tracing.
*: http://en.wikipedia.org/wiki/Depth-first_search
Bonus: This paper on traversal algorithms for Kd-trees in Ray Tracing: Review: Kd-tree Traversal Algorithms for Ray Tracing (http://dcgi.felk.cvut.cz/home/havran/ARTICLES)/cgf2011.pdf
Indeed nodes of a binary tree are often implemented with pointers to the left and right child and the parent (see this implementation of red black trees).
But you not always need a parent pointer:
For an inorder-traversal you can use a recursive algorithm so that the call stack takes care of that for you.
If you want to access the min or max node you can simply maintain a extra pointer to them.
Sometimes you can use a finger tree.
Or organize your pointers extra clever (see Self adjusting binary search trees page 666):
The left pointer of a node points to the first (left) child
The right pointer of a node points to either the sibling (if it is a left child) or back to the parent (if it is a right child)
Extra cool: Threaded binary search trees for extra easy inorder (and reverse order) traversal without a stack - so O(1) space!

iterative approach for tree traversal

Can someone help me out with an algorithm to traverse a binary tree iteratively without using any other data structure like a stack
I read somewhere we can have a flag named visited for each node and turn in on if the node is visited but my BinaryTreeNode class does not have a visited variable defined. So I can not potentially do something like node.left.visited = false
Is there any other way to traverse iteratively?
One option would be to thread the binary tree.
Whenever some node points to NULL (be it left or right), make that node point to the node which comes next in its traversal (pre-order, post-order, etc). In this way, you can traverse the entire tree in one iteration.
Sample threaded binary tree:
Note that left node of each node points to the largest value smaller than it. And the right node of each node points to the smallest value larger than it. So this gives an in-order traversal.

Stackless pre-order traversal in a binary tree

Is it possible to perform iterative *pre-order* traversal on a binary tree without using node-stacks or "visited" flags?
As far as I know, such approaches usually require the nodes in the tree to have pointers to their parents. Now, to be sure, I know how to perform pre-order traversal using parent-pointers and visited-flags thus eliminating any requirement of stacks of nodes for iterative traversal.
But, I was wondering if visited-flags are really necessary. They would occupy a lot of memory if the tree has a lot of nodes. Also, having them would not make much sense if many pre-order tree traversals of a binary-tree are going on simultaneously in parallel.
If it is possible to perform this, some pseudo-code or better a short C++ code sample would be really useful.
EDIT: I specifically do not want to use recursion for pre-order traversal. The context for my question is that I have an octree (which is like a binary tree) which I have constructed on the GPU. I want to launch many threads, each of which does a tree-traversal independently and in parallel.
Firstly, CUDA does not support recursion.
Seoncdly, the concept of visited flags applies only for a single traversal. Since many traversals are going on simultaneously , having visited-flags field in the node data structure is of no use. They would make sense only on the CPU where all independent tree traversals are/can be serialised. To be more specific, after every tree-traversal we can set the visited-flags to false before performing another pre-order tree-traversal
You can use this algorithm, which only needs parent pointers and no additional storage:
For an inner node, the next node in a pre-order traversal is its leftmost child.
For a leaf node: Keep going upwards in the tree until you are coming from the left child of a node with two children. That node's right child will then be the next node to traverse.
function nextNode(node):
# inner node: return leftmost child
if node.left != null:
return node.left
if node.right != null:
return node.right
# leaf node
while (node.parent != null)
if node == node.parent.left and node.parent.right != null:
return node.parent.right
node = node.parent
return null #no more nodes
You can give each leaf node a pointer to the node that would come next in according to a preorder traversal.
For example, given the binary tree:
A
/ \
B C
/ \
D E
\
F
D would need to store a pointer to E, and F would need to store a pointer to C. Then you can simply traverse the tree iteratively as if it were a linked list.
You can do it with no extra storage by storing the same pointer in both the left and right subtree nodes. Since such a structure is not allowed in a tree (that would make it a DAG), you can safely infer that any node where all "child" pointers point to the same place is a leaf node.
You could add a single bit at each node signifying whether the first sub-branch addition went left-ward or rightward... Then, iterating through the tree allows choosing the original direction at every branch.
If you insist on doing this, you could number every possible path through the tree, and then set each worker to follow that path.
Your numbering scheme can simply be that each zero-bit means take the left child, and each one-bit means take the right child. To execute a depth-first search, process your number from least-significant bit to most-significant.
While it is not necessary to know the depth of the tree in advance, if you don't you will need to handle the case where all further numbers hit a leaf before the number is fully consumed.
There is a hack using the absolute values of the {->left,->right} pointers to encode one bit per node. It needs a first pass to get the initial pointer-"polarity" right.
It seems to be called DSW.
You can find more in this https://groups.google.com/group/comp.programming/browse_thread/thread/3552ea0af2006b28/6323076923faec26?hl=nl&q=tree+transversal&lnk=nl& usenet thread.
I don't know if it can be expanded to quad-trees or oct-trees, and I seriously doubt if it can be extended to multithreaded access. Adding a parent pointer is probably easier...
One direction you might want to consider is to delete the nodes of the tree as you traverse them and insert those nodes into a new tree. If you insert nodes in preorder, the new tree is going to be exactly same. But the problem here is how do you maintain integrity of the original tree as you delete items.

tree traverse recursive in level-first order and depth-first order

Is there any algorithm can traverse a tree recursively in level-first order and non-recursively in postorder.Thanks a lot.
To get an effectively recursive breadth-first search you can use iterative deepening depth-first search. It's particularly good for situations where the branching factor is high, where regular breadth-first search tends to choke from excessive memory consumption.
Edit: Marcos Marin already mentioned it, but for the sake of completeness, the Wikipedia page on breadth-first traversal describes the algorithm thus:
Enqueue the root node.
Dequeue a node and examine it.
If the element sought is found in this node, quit the search and return a result.
Otherwise enqueue any successors (the direct child nodes) that have not yet been discovered.
If the queue is empty, every node on the graph has been examined – quit the search and return "not found".
Repeat from Step 2.
Note: Using a stack instead of a queue would turn this algorithm into a depth-first search.
That last line is, obviously, interesting to you if you want to do a non-recursive depth-first traversal. Getting pre- or post-order is just a matter of modifying how you append the nodes in step 2.b.
You can recurse a tree in post order iteratively by using a stack instead of the implicit call stack used in recursion.
Wikipedia says,
Traversal
Compared to linear data structures
like linked lists and one dimensional
arrays, which have only one logical
means of traversal, tree structures
can be traversed in many different
ways. Starting at the root of a binary
tree, there are three main steps that
can be performed and the order in
which they are performed defines the
traversal type.
These steps (in no
particular order) are: performing an
action on the current node (referred
to as "visiting" the node), traversing
to the left child node, and traversing
to the right child node. Thus the
process is most easily described
through recursion.
To traverse a non-empty binary tree in
preorder, perform the following
operations recursively at each node,
starting with the root node:
Visit the node.
Traverse the left subtree.
Traverse the right subtree. (This is also called Depth-first
traversal.)
To traverse a non-empty binary tree in
inorder, perform the following
operations recursively at each node:
Traverse the left subtree.
Visit the node.
Traverse the right subtree. (This is also called Symmetric traversal.)
To traverse a non-empty binary tree in
postorder, perform the following
operations recursively at each node:
Traverse the left subtree.
Traverse the right subtree.
Visit the node.
Finally, trees can also be traversed
in level-order, where we visit every
node on a level before going to a
lower level. This is also called
Breadth-first traversal.

Resources