I have been implementing a heap in C++ using a vector. Since I have to access the children of a node (2n, 2n+1) easily, I had to start at index 1. Is it the right way? As per my implementation, there is always a dummy element at zeroth location.
Your way works. Alternatively you can have root at index 0 and have children at 2n+1 and 2n+2
While this works well for heaps, you end up using a huge amount of redundant memory for other tree data structures that do not necessarily have a full and complete Binary tree. For example, this means that if you have a Binary search tree of 20 nodes with a depth of 5, you end up having to use an array of 2^5=32 instead of 20. Now imagine if you need a tree of 25 nodes with a depth of 22. You end up using a huge array of 4194304, whereas you could have used a linked representation to store just the 25 nodes.
You can still use an array and not incur such a memory hit. Just allocate a large block of memory as an array and use array indices as pointers to the children.
Thus, where you had
node.left = (node.index*2)
node.right = (node.index*2+1)
You simply use
node.left = <index of left child>
node.right = <index of right child>
Or you can just use pointers/references instead of integer indices to an array if your language supports it.
Edit:
It might not be obvious to everyone that a complete binary search tree takes up O(2^d) memory. There are d levels and every level has twice as many nodes as the level its parent is in (because every node except those at the bottom has exactly two children - never one). A binary heap is a binary tree (but not a Binary Search Tree) that is always complete by definition, so an array based implementation outlined by the OP does not incur any real memory overhead. For a heap, that is the best way to implement it in code. OTOH, most other binary trees (esp. Binary Search Trees) are not guaranteed to be complete. So trying to use this approach on would need O(2^depth) memory where depth can be as large as n, where we only need O(n) memory in a linked implementation.
So my answer is: yes, this is the best way for a heap. Just don't try it for other binary trees (unless you're sure they will always be complete).
Related
I am currently learning data structure and trying to implement a BST and max-heap(use BST as base class). But I accidentally found it seems impossible to derive heap from BST. Almost all the implementation for heap are based on array rather then using pointers point to left and right, and most of BST are based on pointers rather than array.
So my question is why I have to use array to realize a heap? And, in realizing BST, why people choose to use pointers point to left and right rather array? I know use array to realize BST may cost more space, and it is harder to implement remove function, is there any more reason for that?
Thank you so much!
The main reason standard implementation of binary heaps is done using arrays is because heaps are complete binary trees.
Because complete binary trees always grow level by level(Meaning:First the parent level will be filled with nodes and only then the child level is filled).
Therefore,We are able to use arrays where for a node at position i, the left child is found at position 2*i and right child is found at position 2*i+1.
The reason that binary search trees is implemented using pointers and not using arrays is because binary search trees are not guaranteed to be complete binary trees
I have a tree Node whose data is a string.
class node{
private:
string data;
node *left,*right;
}
And now i have an array of tree nodes where I have appended the contents of multiple file into the an array of Binary Tree.
Now I want to perform a Binary Search of a key Paralyze. Is it possible ?? As I'm aware that only the address of the root is stored in the elements of the array. Is it possible to copy the contents of the tree to the Device.?? Please do suggest me a search algorithm that is efficient than 2D array linear search . If i copy the whole array of tree would it still be efficient?
As I understand from your question, you have an array of elements that represent the roots of many binary trees. If you want to send this array to your device, I would suggest to transform each tree in a sorted vector and perform binary search on each vector. That is, you will have an array of sorted arrays.
Now you can perform parallel binary search on all sub-arrays. You even can split each sorted array into groups and perform binary search on each group.
Depending on the use-case, the memory transfer might be the bottleneck, much more expensive than the search. Hence, you want to be very careful in the way you allocate memory. Using a node allocator that arranges nodes and pointers in arrays is good idea. Though, you may enter the following issues:
pointer may not be valid in both address spaces, you hence want to either use indices in arrays or unified memory to do this on a GPU.
to my knowledge, std::string is not supported in CUDA as discussed here, you then might prefer char* to point to string data (which should also be available in GPU memory space, hence a dedicated string storage system).
It is then possible to parallelize your search but the benefits will strongly depend on the number of trees you want to search. If it is small compared to the number of CUDA threads running on GPU (i.e. thousands), benefits are uncertain.
Searching some value in a small set might be better on GPU using technique similar to reduce (see scalar prod example in CUDA GPU Computing SDK), rather than actually building a tree.
I'm prepping for a Google developer interview and have gotten stuck on a question about heaps. I need to implement a heap as a dynamic binary tree (not array) where each node has a pointer to the parent and two children and there is a global pointer to the root node. The book asks "why won't this be enough?"
How can the standard tree implementation be extended to support heap operations add() and deleteMin()? How can these operations be implemented in this data structure?
Can you keep the size of total nodes ? if so, it's easy to know where you should add new element, because that's an almost full tree.
About deleteMin, I think that it will be less effective because you can't access directly to all leaves, as in array (N/2).
You should travel through all paths till you get leaf and then compare them, probably it will cost O(n)
Is it possible to traverse a tree structure (specifically an octree, the 3-D version of a binary tree) by using a fixed sized stack? I do not want to use recursion, since my octree is
quite deep.
I am traversing the tree to do a range search problem, to find all the points closest to a queried point. So in my traversal, I do not walk down those subtrees rooted at nodes which my search region does not intersect.
If your octree has parent pointers, I think you can traverse it without a stack at all (see this thread, for example). Without that, you will need a stack that is as deep as the depth of your tree, regardless of how many branches are skipped.
Of course you can traverse a tree without using a deep native call stack, using continuation passing style techniques, or (and this is grossly the same) by making a virtual machine, with its call stack implemented as a heap data, or (yet another point of view) by coding a stack automata with the stack implemented as an explicit heap data structure (e.g. a std::stack).
Think of it otherwise, your C++ naive code could run on a Turing machine, and these beasts don't have any stack.
As Ted Hopp's answer suggests, you might be inspired by Deutsch-Schorr-Waite's Garbage Collection techniques (with a few additional bits per node to temporarily flip the reference direction and remember that) to have a "stack-less" traversal (but you need additional bits in each node). But I believe that having your own stack inside a std::stack or std::vector is probably simpler.
Yes, you can traverse the octree with a fixed-size stack.
The fixed-size just needs to be as big as the longest possible octree depth.
Bear in mind that with an octree, each depth traversal can be recorded with only 3 bits of memory. For each of the three dimensions, you only need to record whether you went in a positive or negative direction.
So even if your octree goes 1000-deep, you can store the recursion with 375 bytes.
I found lots of MinMax Heap implementations, that were storing data in an array. It is realy easy to implement, that is way I am looking for something different. I want to create a MinMax Heap using only elements of the Heap with pointers to left child and right child (and afcourse a key to compare). So the Heap have only pointer to the root object (min level), and a root object have a pointer to his children (max level) and so on. I know how to insert a new object (finding a proper path by using binary represenation of int depending on Heap size), but I don't know how to implement the rest (push up (down) the element, find parent or grandparent).
Thx for help
A priority queue using a heap ordered binary tree can be implemented using a triply linked list structure instead of an array. you will need three links per node:two to traverse down and one to traverse up.
The heapq module source code shows to implement the steps for pushing up and down. To switch from an array implementation to a pointer implementation, replace the arr[2*n+1] computation with node.left and arr[2*n+2] with node.right. For parent references such as arr[(n-1)>>1], every node will need a pointer to its parent, node.parent.
Alternatively, you can adopt a functional style which makes this all very easy to implement. I found the code for treaps implemented in Lisp to be an inspiration for how to do this.
I have solved this problem as part of an assignment long back. You can find it here
I have multiple implementations in Java and C++ implementing MinHeap with and without arrays. See my Java implementations for the solution. And yes it is very much possible to implement Heap without arrays. You just have to remember where to insert the next node and how to heapify and reverse heapify.
Edit1: I also tried to look up any existing solutions for min heap without arrays but couldn't find any. So, I am posting it here so it could be helpful for anyone who wishes to know the approach.
Yes, you can implement it without relying on an array.
I personally relied on a binary counter...
Here is my implementation(https://github.com/mohamedadnane8/HeapsUsingPointers) in c.
Note that this is still a very fast implementation with log(n).
1 => binary "1"
2=> "10" 3=> "11"
4=> "100" 5= "101" 6="110" 7="111"
In this program i tried to use the sequence of numbers to insert and delete as u can see above the tree can be easily represented as binary strings of numbers.
The first '1' in the binary string is to start.
After that the sequence of 0 and 1 determines where to go '1' means go to the left and '0' go to the right.
Also, note that this implementation relies on a very small array of characters or integers that make the calculation of the binary numbers faster but u can rely on bin() function to convert ur counter to a binary number(I implemented the array just to practice a bit my problem-solving skills).
Sorry if I couldn't explain it very well, I lack a bit in my communication skills.
It is hard implement binary heap without array. Because you should keep all the parent while inserting you pass and then do operation push up and down. like that [parent_1, parent_2 ... parant_k] and then if parent_(k+1) < parant_k pushUp and rearrange their right child and left child