// heap.h
#include < fstream.h >

typedef unsigned long long reallong;

bool minHeapCompare (void *, void *);

bool maxHeapCompare (void *, void *);

class TreeObject {
 public:
   virtual void display (ostream & out) { out << "Something is wrong!\n"; }
   virtual reallong value ()  { return 0; }
};

class Cell {
friend class BinTree;
friend class Heap;
friend ostream & operator<<(ostream & out, BinTree & bt);
   TreeObject *object;
   Cell *leftnext, *rghtnext, *lefttree, *rghttree, *parent;
   Cell (TreeObject *obj, Cell *ln, Cell *prnt);
   Cell (TreeObject *obj, Cell *ln);
};

/***--------------------------------------------------------------------***/
/***  The class of Binary Trees -                                       ***/
/***    includes the following methods, among others                    ***/
/***       1. HeapifyDown - percolate an object down from the root      ***/
/***       2. HeapifyUp   - percolate an object up from a leaf          ***/
/***       3. popNode     - delete the last Cell and return its object  ***/
/***       4. setRoot     - replace an object at the root with another  ***/
/***       5. HeapSort    - repeat: setRoot(popNode()); heapifyDown();  ***/
/***       6. addNodeToHeap - add a Cell to end of heap and add object  ***/
/***    saves information in the following variables                    ***/
/***       1. dispfn      - pointer to function that displays the tree  ***/
/***       2. valfn       - pointer to function returning value of obj  ***/
/***       3. head, tail  - pointers locating root and end of tree      ***/
/***    tail pointer -                                                  ***/
/***       1. points to a leaf Cell if the tree has an odd number of    ***/
/***          Cells.  It either points to the leftmost childless Cell   ***/
/***          in the row that is one up from the bottom, or, in the     ***/
/***          case of a full tree, it points to the leftmost Cell of    ***/
/***          the bottom level (latter case covers the one-Cell case).  ***/
/***       2. points to the rightmost Cell, one level up from the       ***/
/***          bottom, that has a child.                                 ***/
/***--------------------------------------------------------------------***/
class BinTree {
friend ostream & operator<< (ostream & out, BinTree & bt);
 protected:
   Cell *head, *tail;
   
 public:
   BinTree() { head = tail = NULL;  } 
   bool  empty()   {  return head == NULL;  }
   void  displayRoot() { cout << head->object->value() << " "; }   
   TreeObject *getRoot();
   TreeObject *popNode();
   void  putRoot(TreeObject *t);
   void  addNode(TreeObject *t);
};

class Heap : public BinTree {
   bool (* cmp)(void *, void *);
public:
   Heap(bool (* f)(void *, void *)) : BinTree() { cmp = f; }
   void  heapifyDown();
   void  heapifyUp();
   void  heapifyUpFrom(Cell *c);   
   void  addNode(TreeObject *t);    // Override
   void  insert(TreeObject *t);     // Override
   void  heapSort();
   ostream & display(ostream &);
   TreeObject *popRoot();
   TreeObject *dequeue();
};