//----------------------------------------------------------------------
//  SPECIFICATION FILE (chartree.h)
//  This module exports 1) CharTree, an ADT for an unbounded
//  binary tree whose nodes contain char values, 2) a pointer type
//  NodePtr for accessing nodes in a tree, and 3) operations on
//  tree nodes.
//----------------------------------------------------------------------
#include "bool.h"

/*---------------------------------------------------------------*/
/*               Notation Used in Assertions                     */
/*---------------------------------------------------------------*/
/* ValidNode(n) means                                            */
/*    n is some node that has been placed in the binary tree via */
/*    BuildRoot (of CharTree class), AppendLeft, or AppendRight  */
/* Contents(n) means                                             */
/*    the data stored in node n of the tree                      */
/* HasLeftChild(n) means                                         */
/*    node n has some left child, LC, AND ValidNode(LC)          */
/* HasRightChild(n) means                                        */
/*    node n has some right child, RC, AND ValidNode(RC)         */
/* IsLeaf(n) means                                               */
/*    NOT HasLeftChild(n) AND NOT HasRightChild(n)               */
/*---------------------------------------------------------------*/

struct TreeNode;            // Complete declaration hidden in
                            // implementation file
typedef TreeNode* NodePtr;

class CharTree {
public:
    Boolean IsEmpty() const;
        // POST: FCTVAL == (tree has no nodes)

    void BuildRoot( /* in */ char someChar );
        // PRE:  IsEmpty()
        // POST: Tree has root node, call it R
        //    && Contents(R) == someChar  &&  IsLeaf(R)

    NodePtr Root() const;
        // POST: FCTVAL == NULL, if IsEmpty()
        //              == pointer to root node, otherwise

    CharTree();
        // Constructor
        // POST: Created(tree)  &&  IsEmpty()
private:
    NodePtr rootPtr;
};

//......................................................................
// The following operations manipulate nodes indirectly
// through pointers of type NodePtr
//......................................................................

void AppendLeft( /* in */ NodePtr ptr,
                 /* in */ char    someChar );
    // PRE:  ValidNode(*ptr)  &&  Assigned(someChar)
    // POST: New node, call it LC, created as left child of *ptr
    //    && ValidNode(LC)  &&  IsLeaf(LC)  &&  Contents(LC) == someChar
    // NOTE: Dangling pointers may occur if HasLeftChild(*ptr<entry>)

void AppendRight( /* in */ NodePtr ptr,
                  /* in */ char    someChar );
    // PRE:  ValidNode(*ptr)  &&  Assigned(someChar)
    // POST: New node, call it RC, created as right child of *ptr
    //    && ValidNode(RC)  &&  IsLeaf(RC)  &&  Contents(RC) == someChar
    // NOTE: Dangling pointers may occur if HasRightChild(*ptr<entry>)

char Data( /* in */ NodePtr ptr );
    // PRE:  ValidNode(*ptr)  &&  Assigned(Contents(*ptr))
    // POST: FCTVAL == Contents(*ptr)

void Store( /* in */ NodePtr ptr,
            /* in */ char    someChar );
    // PRE:  ValidNode(*ptr)  &&  Assigned(someChar)
    // POST: Contents(*ptr) == someChar

NodePtr LChild( /* in */ NodePtr ptr );
    // PRE:  ValidNode(*ptr)
    // POST: FCTVAL == NULL, if NOT HasLeftChild(*ptr)
    //              == pointer to left child of *ptr, otherwise

NodePtr RChild( /* in */ NodePtr ptr );
    // PRE:  ValidNode(*ptr)
    // POST: FCTVAL == NULL, if NOT HasRightChild(*ptr)
    //              == pointer to right child of *ptr, otherwise

Boolean IsLeaf( /* in */ NodePtr ptr );
    // PRE:  ValidNode(*ptr)
    // POST: FCTVAL == IsLeaf(*ptr)

void DeleteLeaf( /* inout */ NodePtr& ptr );
    // PRE:  IsLeaf(*ptr<entry>)
    // POST: *ptr<entry> removed from tree  &&  ptr is undefined

