The 101 of elf binaries on linux understanding and analysis25 comments
Center topoptio com
Each of its children have their children and so on. The nodes without children are leaf nodes 3 , 4 , 5 , 6.
The number of edges between root and leaf nodes define tree height. The tree above has the height 2. Standard approach to implement binary tree is to define class called BinaryNode. However, there is a trick to implement binary tree using only static arrays. If you enumerate all nodes in binary tree by levels starting from zero you can pack it into array. The relationship between parent index and child index, allow us to move from the parent to child, as well as from the child to the parent.
Important note that the tree should be complete , what means for the specific height it should contain exactly elements. You can avoid such requirement by placing null instead of missing elements. The enumeration still applies for empty nodes as well.
This should cover any possible binary tree. Such array representation for binary tree we will call Binary Tree Array. We always assume it will contain elements. There are two search algorithms exist for binary tree: BFS search nodes level by level, starting from the root node.
Then checking its children. Then children for children and so on. Until all nodes are processed or node which satisfies search condition is found. It checks all nodes from leftmost path from the root to the leaf, then jumps up and check right node and so on. For example, assume you need to find node with value 1 in the following tree. Yellow cell are cells which are tested in search algorithm before needed node found.
Take into account that for some cases DFS require less nodes for processing. For some cases it requires more. Breadth-first search for binary tree array is trivial.
Since elements in binary tree array are placed level by level and bfs is also checking element level by level, bfs for binary tree array is just linear search. Using stack data structure it could be implemented the same way as for classic binary tree, just put indices into the stack.
From this point recursion is not different at all, you just use implicit method call stack instead of data structure stack. What if we could implement DFS without stack and recursion. In the end is just a selecting correct index on each step? As in BFS we start from the root index 0.
If next left child produce index out of array bounds exception we need to stop doubling and jump to the right child. The observation here is the number of elements in the tree of some height is two times larger and plus one than the tree with height - 1. We can run doubling, and we even know when to stop. But this way we can check only left children of the nodes.
When we stuck at the leaf node and can not apply doubling anymore, we perform jump operation. Basically, if doubling is go to left child, jump is go to parent and go to right child. Such jump operation can be implemented by just incrementing the leaf index. So we need to do double jump. Make it more generic, for our algorithm we could define operation jump N , which specifies how many jumps to the parent it requires and always finishes with one jump to the right child.
For the tree with height 2 , we need one jump, one double jump, and than one jump again. For the tree with height 3 , you can apply the same rules and get 7 jumps. If you apply the same rule to the tree of height 4 and write down only jump values you will get next sequence number. This sequence known as Zimin words and it has recursive definiton, which is not great, because we not allowed to use recursion. We can track index for current leaf j , which corresponds to the index in sequence array above.
Obviously, BFS on array wins. Iterative DFS, which we just described in the article, took 2 nd place and 4. The rest three algorithms even slower then iterative DFS, probably, because they involve additional data structures, extra space and memory allocation.
Binary Tree Array is a nice trick to represent hierarchical data structure as a static array contiguous region in the memory. It defines a simple index relationship for moving from parent to child, as well as moving from child to parent, which is not possible with classic binary array representation.
As we have shown, search algorithms, BFS and DFS implemented on arrays are much faster then their brothers on a reference based structure.
Anyway, it was a nice excercise. Binary Tree Array This is binary tree.