Samuel Jacob's Weblog

Just another technical blog

Self Balancing Tree as Heap

without comments

Here is my thoughts about how to combine a Heap and AVL tree and get benefit of both them from a single data structure.

A self balancing binary search tree such as AVL tree can do faster lookup for a item in the tree in O(log n). Heaps are mainly used to implement priority queues which needs to find min/max elements quickly. Heap achieves this in O(1) time complexity.

Balanced BST1 Lets revisit a basic property of binary search tree – In a binary search tree min element is at the left most leaf position. Similarly in a BST max element is at the right most leaf position. So finding min/max element in a BST is O(h) where h is the depth of the tree. If the BST is a balanced tree then O(h) is O(log n) in worst case(otherwise the worst case O(n), since we considering only balanced trees here lets ignore the unbalanced cases). The following diagram illustrates a basic property of the BST – min element is always on the left most node.

Cached pointer to Min element at the root

Cached pointer to Min element at the root

Using this basic property, min remove operation can be optimized. The first and simplest optimization comes to mind is store a pointer to min/max elements. This caching will result in O(1) time complexity for finding min/max elements. However this would increase the cost of node insert/delete because the min/max pointer has to be updated during insert and deletion. The cost of finding and deleting a min node is O(log(n)) which is same as if we havent had the cache pointers. The picture in the right shows advantage of having cached pointer to find a min element. Obviously this method cant be used for priority queues where find min/delete operation is used together.

In the above method the problem was the complexity finding next smallest element in the tree from min element is O(log n). So if we have pointer to next smallest element from all nodes then find and delete opearation would be of complexity O(1).

Lets look at the BST from slightly different angle. Usual declaration of BST in C as follows:

[c]
struct binary_tree
{
struct binary_tree *left;
struct binary_tree *right;
};
[/c]

When we(me and +Dilip Simha) were implementing ADT for AceOS we decided to experiment BST in a different way. We saw tree as recursive lists rather than a recursive pointers.

In the following picture you could see 6 lists(not counting sub-lists):
A list is highlighted

  1. (300, 200, 100, 50)
  2. (300, 400, 500, 600)
  3. (200, 250, 275)
  4. (100, 150)
  5. (400, 350)
  6. (500, 450)

Now consider this list is a doubly linked circular list. This is illustrated in the following figure. You may argue that this will make the BST to become cyclic directed graph. But for the sake of simplicity lets continue to call this as balanced BST. In the picture I left out few arrows to keep it cleaner.

Binary Search Tree with nodes having pointer to parent also

Binary Search Tree with nodes having pointer to parent also

[c]
typedef struct list LIST, * LIST_PTR;
struct list {
LIST_PTR next;
LIST_PTR prev;
};

typedef struct binary_tree
{
LIST left;
LIST right;
}BINARY_TREE;

typedef struct avl_tree
{
int height; /*! height of the node*/
BINARY_TREE bintree; /*! low level binary tree*/
}AVL_TREE;
[/c]

AVL tree in Ace OS  is implemented in this way. You can see the data structure declarations below. Initially we did it for reusing the code. But after implementing this we figured out some interesting properties. This balanced tree/graph can find any node in O(log(n)) and also offers findmin operation in O(1) complexity. This also reduces the complexity of delete operation(since we can find right node’s left most child in O(1) operation). But delete operation might result in balancing the tree.

Written by samueldotj

May 11th, 2013 at 11:59 am

Posted in Ace