//----------------------------------------------------------------------
//  IMPLEMENTATION FILE (inttree.cpp)
//  This module is identical to CharTree except IntTree objects
//  are trees of integers, not trees of characters.
//----------------------------------------------------------------------
#include "inttree.h"
#include <stddef.h>      // For NULL

struct TreeNode {
    int     data;                        // Data member
    NodePtr lLink;                       // Pointer to left child
    NodePtr rLink;                       // Pointer to right child
    TreeNode( int, NodePtr, NodePtr );   // Constructor
};

TreeNode::TreeNode( /* in */ int     someInt,
                    /* in */ NodePtr leftPtr,
                    /* in */ NodePtr rightPtr )
    //..................................................................
    // POST: data == someInt  &&  lLink == leftPtr  &&  rLink == rightPtr
    //..................................................................
{
    data = someInt;  lLink = leftPtr;  rLink = rightPtr;
}

// Private members of IntTree class:
//    NodePtr rootPtr;               Pointer to root node

IntTree::IntTree()
    //..................................................................
    // POST: rootPtr == NULL
    //..................................................................
{
    rootPtr = NULL;
}

Boolean IntTree::IsEmpty() const
    //..................................................................
    // POST: FCTVAL == (rootPtr == NULL)
    //..................................................................
{
    return (rootPtr == NULL);
}

void IntTree::BuildRoot( /* in */ int someInt )
    //..................................................................
    // PRE:  rootPtr == NULL
    // POST: rootPtr points to newly allocated node, call it N
    //    && N.data == someInt  &&  N.lLink == NULL  &&  N.rLink == NULL
    //..................................................................
{
    rootPtr = new TreeNode(someInt, NULL, NULL);
}

NodePtr IntTree::Root() const
    //..................................................................
    // POST: FCTVAL == rootPtr
    //..................................................................
{
    return rootPtr;
}

void AppendLeft( /* in */ NodePtr ptr,
                 /* in */ int     someInt )
    //..................................................................
    // PRE:  ptr != NULL  &&  Assigned(someInt)
    // POST: ptr->lLink points to newly allocated node, call it LC
    //    && LC.data == someInt  &&  LC.lLink == NULL  &&  LC.rLink == NULL
    //..................................................................
{
    ptr->lLink = new TreeNode(someInt, NULL, NULL);
}

void AppendRight( /* in */ NodePtr ptr,
                  /* in */ int     someInt )
    //..................................................................
    // PRE:  ptr != NULL  &&  Assigned(someInt)
    // POST: ptr->rLink points to newly allocated node, call it RC
    //    && RC.data == someInt  &&  RC.lLink == NULL  &&  RC.rLink == NULL
    //..................................................................
{
    ptr->rLink = new TreeNode(someInt, NULL, NULL);
}

int Data( /* in */ NodePtr ptr )
    //..................................................................
    // PRE:  ptr != NULL  &&  Assigned(ptr->data)
    // POST: FCTVAL == ptr->data
    //..................................................................
{
    return ptr->data;
}

void Store( /* in */ NodePtr ptr,
            /* in */ int     someInt )
    //..................................................................
    // PRE:  ptr != NULL  &&  Assigned(someInt)
    // POST: ptr->data == someInt
    //..................................................................
{
    ptr->data = someInt;
}

NodePtr LChild( /* in */ NodePtr ptr )
    //..................................................................
    // PRE:  Assigned(ptr)
    //    && (ptr != NULL) --> Assigned(ptr->lLink)
    // POST: FCTVAL == NULL, if ptr == NULL
    //              == ptr->lLink, otherwise
    //..................................................................
{
    return (ptr==NULL) ? NULL : ptr->lLink;
}

NodePtr RChild( /* in */ NodePtr ptr )
    //..................................................................
    // PRE:  Assigned(ptr)
    //    && (ptr != NULL) --> Assigned(ptr->rLink)
    // POST: FCTVAL == NULL, if ptr == NULL
    //              == ptr->rLink, otherwise
    //..................................................................
{
    return (ptr==NULL) ? NULL : ptr->rLink;
}

Boolean IsLeaf( /* in */ NodePtr ptr )
    //..................................................................
    // PRE:  ptr != NULL
    // POST: FCTVAL == (ptr->lLink == NULL  &&  ptr->rLink == NULL)
    //..................................................................
{
    return (ptr->lLink == NULL && ptr->rLink == NULL);
}

void DeleteLeaf( /* inout */ NodePtr& ptr )
    //..................................................................
    // PRE:  Assigned(ptr)
    // POST: *ptr deallocated
    //..................................................................
{
    delete ptr;
}

