views:

79

answers:

2

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.

+3  A: 

Your way works. Alternatively you can have root at index 0 and have children at 2n+1 and 2n+2

codaddict
Or, equivalently, do all the math as described in the question (base 1), but use a custom operator[] which subtracts 1 from its index.
Steve314
+1  A: 

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).

MAK
Deleted my comments. I acknowledge the first was plain wrong (didn't read your answer properly). I still don't understand why you raised the subject of BSTs, but I also don't know why I've been making a big deal out of it.
Steve314
@Steve314: The other answer already said that this approach works well with heap, I just thought I'd explain a bit and demonstrate that while this is good for heaps, its not always the best for every sort of tree that's all.
MAK