An Example of Good Documentation Style

CSCI 151 – section 04

 

 

 

PROGRAM: AVL TREE

 

 


AVLTREE.H

 

 


// AVLTree.h: interface for the AVLTree class.

//

//////////////////////////////////////////////////////////////////////

 

 

/****************************************************************

 * Name:  XXXXXXXXXXXXXXXXXXX                                    

 *

 * Class  Computer Science 151                                               

 *

 * Assignment: Program 2                                                     

 *

 *                                                                           

 *

 ****************************************************************

 

Program 2:  AVLTrees

 

 

Status Of Program:            Completed

 

      main()                        Complete and Tested

      Usage()                       Complete and Tested

      Class AVLTree                 Complete and Tested

            AddKeyItem()                        Complete

            AVLTree()                           Complete

            ~AVLTree()                          Complete

            BalanceStack()                      Complete

            DebugCheckTree()                    Complete

            DebugVerifyTree()                   Complete

            DeleteKeyItem()                     Complete

            DeleteTree()                        Complete

            FindImmediatePredecessor()          Complete

            FindImmediateSuccessor()            Complete

            GetStatusMessage()                  Complete

            InOrderTraversal()                  Complete

            LocateInsertDeletePosition()        Complete

            NodeBalanceFactor()                 Complete

            NodeHeight()                        Complete

            PostOrderTraversal()                Complete

            PreOrderTraversal()                 Complete

            PrintNode()                         Complete

            PrintNodeData()                     Complete

            Rebalance()                         Complete

            Rotate()                            Complete

            SetFileOut()                        Complete

            traverse_AVL_Inorder()              Complete

            traverse_AVL_PostOrder()            Complete   

            traverse_AVL_PreOrder()             Complete

            UnwindAVLStack()                    Complete

            UnwindQueues()                      Complete

 

 

Program Overview:

 

Functional Description:

 

  This program generates an AVL tree, then reads commands from an input file,

  processes those commands and sends the results to the specified output file.

  See the "Commands and Formats" table in the specifications document.

 

 

Operational Description:

The program reads lines from a file specified in the program command line. Each command line is parsed and the commands are selected using the characters specified in the commands and formats table.  Several commands (Add, Delete and Search) have additional fields containing a required integer.  Results are sent to an output file, also specified in the command line.

 

      The command line is AVLTrees CmdFile OutputFile [DEBUG].

 

      CmdFile is the input file with commands.

      OutputFile is the results file.

 

      The DEBUG command line option changes the output format and causes the

      AVLTree::DebugVerifyTree() function to be called after every node addition

      or deletion to check the viability of the code.

 

 

****************************************************************************

Classes

******************************************************************************

 

  AVLTree

      Purpose: The AVL tree is maintained in an AVLTree class.

This class generates the tree and controls all access, additions and deletions.The AVLTree class utilizes a stack and several queues to track movement within the tree.

 

 

      Functions: See the Specifications and Status Document.

                 

 

     

******************************************************************************

Other Objects:

******************************************************************************

      I_Node

            Purpose: Structure defining a the node data to be stored in the AVL

                         tree.

 

     

******************************************************************************

Other Functions:

 

      Usage()

            Purpose:  Displays the instructions to run this program.

      TrimLine()

            Purpose:  Trim the command line (remove spaces from the front and

             back).

 

******************************************************************************

 

 Note:

All functions are original code except for AVLTree::traverse_AVL_Inorder(),AVLTree::traverse_AVL_PostOrder() and  AVLTree::traverse_AVL_PreOrder() which were copied from the examples in the workbook and modified to format the output.

 

*/

 

 

#if !defined(AFX_AVLTREE_H__275508E6_2E7B_11D4_805C_080009B93EFF__INCLUDED_)

#define AFX_AVLTREE_H__275508E6_2E7B_11D4_805C_080009B93EFF__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

#include <stack>

#include <queue>

#include "fstream.h"

 

//***************************************************************************

// AVLTree.h: header file for the AVLTree class.  contains class declarations

// and information.

//

 

 

#define ROTATELEFT  100

#define ROTATERIGHT 101

//*************************************************************

// Structure:  I_Node   (integer node)

// Purpose:    Used by the AVLTree class to hold integer data for the tree

// Archetecure

 

struct I_Node

{

      int iValue;             // KeyValue also data

      I_Node *LeftChild;  // Pointer to the LeftChildNode

      I_Node *RightChild; // Ponter to the RightChildNode

      int iHeight;            // position in the tree from the bottom

                                    // if this is a leaf node it will have a 0 height

                                    // this is an absolute value

      int iBalanceFactor; // Right child height - left child height

      //

      //

      //

      I_Node()                // Constructor for I_Node

      {

          LeftChild=NULL;

            RightChild=NULL;

            iHeight=0;

            iBalanceFactor=0;

      }   // constructor

      //

};

 

//*************************************************************

// Class:  AVLTree

// Purpose: Implement an AVL Tree with an integer key and provide the

//appropriate access to the tree.

//

//        

//

// Implementation Note:  We want to convert this to a template in the future.

class AVLTree 

{

public:

      AVLTree();              //Constructor:  initializes Class variables

      virtual ~AVLTree(); //Destructor:   Deallocates any memory allocated

 

      void SetFileOut(ofstream *ofile);   // Set the target file

      char * GetStatusMessage();                // Results of previous operation

      I_Node * AddKeyItem(int ivalue);    // Add a node to the tree

      bool DeleteKeyItem(int iValue);           // Remove a node from the tree

      I_Node * FindValue(int iSearchKey);   // Search for the key in the tree

 

      //

      //

      // Traversals

      //

      void PostOrderTraversal(ofstream *ofile);

      void PreOrderTraversal(ofstream *ofile);

      void InOrderTraversal(ofstream *ofile);

     

 

private:          //Functions

 

 

      void BalanceStack();

      int DebugCheckTree(I_Node *itree_ptr);

      void DebugVerifyTree();

      void DeleteTree(I_Node *rootptr);

      int FindImmediateSuccessor(I_Node *inode);

      int FindImmediatePredecessor(I_Node *inode);

      I_Node * LocateInsertDeletePosition(int iValue);

      int NodeBalanceFactor(I_Node *inode);

      int NodeHeight(I_Node *inode);

      void PrintNode(I_Node *inode);

      void PrintNodeData(I_Node *inode, bool bPrintTitle=false);

      void Rebalance(I_Node *UnBalancedNode, I_Node *ParentOfUnBalancedNode);

      void Rotate(int iRotateType,I_Node *PivotNode, I_Node *ParentNode);

      void traverse_AVL_PostOrder(I_Node *itreeptr);

      void traverse_AVL_PreOrder(I_Node *treeptr);

      void traverse_AVL_Inorder(I_Node *itree_ptr);

      void UnwindAVLStack();

      void UnwindQueues();

 

private:   //Data

      I_Node * Root;                // Pointer to the root node

      int iNodeCount;               // Number of Nodes in the tree

      char StatusString[100]; // What happened in the last operation

      bool bError;                  // Some type of error in the last operation

      bool bFound;                  // Search string was found

      ofstream * OutFile;           // Output File Stream

      //

      // We must specify the std name space here

      // because stack is a Standard Library template

      //

      std::stack<I_Node *> AVLStack;  // Declare the stack

      std::queue<I_Node *> PredecessorQueue;

      std::queue<I_Node *> SuccessorQueue;

 

 

};

 

#endif // !defined(AFX_AVLTREE_H__275508E6_2E7B_11D4_805C_080009B93EFF__INCLUDED_)

 

 

AVLTREE.CPP

 

 


// AVLTree.cpp: implementation of the AVLTree class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "iomanip.h"

#include "AVLTree.h"

extern bool gDebug; //global definition

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

AVLTree::AVLTree()

{

      // FUNCTION: AVLTree()  //Constructor

      //

      // Preconditions: None

      //

      // PostConditions: an empty AVL tree is created

      //

      // Global vars: none

      //

      // Local vars: None

      //

      // Class vars: iNodeCount, Root

      //

      // Function Calls: None

      //

      // Functional Desc: Constructor; Initialize Class variables

      //

      // Operational Desc: Set class variables to their intial condition

     

 

      iNodeCount=0;  // There are no nodes in the tree

      Root = NULL;   // There is no root node

      strcpy(StatusString,"AVLTree Initialized");

}

 

//*********************************************************

AVLTree::~AVLTree()

{

      // FUNCTION: ~AVLTree()  //Destructor

      //

      // Preconditions: The class existed, is now being deleted

      //

      // PostConditions: The tree is deleted, all memory is freed

      //

      // Global vars: none

      //

      // Local vars: None

      //

      // Function Calls:      DeleteTree()

      //                            UnwindQueues()

      //                            UnwindAVLStack()

      //

      // Functional Desc: Deletes the AVL tree and all memory allocated

      // in this calls

      //

      // Operational Desc: Calls DeleteTree() to delete all nodes in the tree.

      //                                     UnwindAVLStack and UnwindQueues

      // to ensure that

      //                          these objects are ready for deletion.

      //

      UnwindQueues();         // Clear the Queue Memory

      UnwindAVLStack(); // Clear the stack memory

      DeleteTree(Root); // Clear the tree

} //AVLTree::~AVLTree()

 

 

//*********************************************************

I_Node * AVLTree::FindValue(int iSearchKey)

{

      // FUNCTION: I_Node * FindValue(int iSearchKey)

      //

      // Preconditions: iSearchKey contains the integer value to search on

      //

      // PostConditions:      Returns a pointer to the node with the matching       //                      value

      //                     

      //                           

      // Global vars: none

      //

      // Class vars: Root

      //

      // Local vars: I_Node *inode

      //

      // Function Calls:sprintf(), strcpy()

      //

      // Functional Desc: Search the tree for a specific value

      //

      // Operational Desc:  Check for a NULL root, indicating an empty tree

      //                    At each node check for a match, then select the  

      //                    direction of the next node based on less than

      //                    or greater than values.

      //                  

     

                             

      //

      // Handle an empty tree

      //

      if (Root == NULL)  //empty tree;

      {

            strcpy(StatusString, "Empty Tree");

            return(NULL);

      }

      //

 

      I_Node *inode=Root;    // set our temp variable to the root node to start

      //

      // check for a match at every node that we traverse.

      //

      while(inode !=NULL)

      {

            //

            // Check for a match

            //

            if (iSearchKey == inode->iValue) //Is this a match

            {

                  sprintf(StatusString,"Node Found: Value = %d ",inode->iValue);

 //Set status

                  return(inode);

            }//   if (iSearchKey == inode->iValue)

 

           

            //

            // Check for greater than

            //

            if (iSearchKey > inode->iValue) // Go down the right hand path

            {

                  if (inode ->RightChild == NULL)

                  {

                        strcpy(StatusString, "Node Not Found");

                        return(NULL);

                  }//if (inode ->RightChild == NULL)

           

                  inode=inode->RightChild;  // getthe next node in the path

            }//if (iSearchKey > inode->iValue)

 

            else // less than

            {     //

                  //

                  if (inode->LeftChild== NULL) // Node does not exist

                  {

                        strcpy(StatusString, "Node Not Found");

                        return(NULL);

                  }//if (inode->LeftChild== NULL)

 

                  inode=inode->LeftChild; // Get the next node in the path

            }//if (iSearchKey > inode->iValue)

 

      }//   while(inode !=NULL)

 

      //

      // if we get to here it is an error

      //

 

 

      strcpy(StatusString,"Error: FindValue : Processing Error");

 

      return(NULL);

 

}//I_Node * AVLTree::FindValue(int iSearchKey)

 

//*********************************************************

 etc………………………………………….

 

 

 


AVLTREES.CPP

 

 

 


// AVLTrees.cpp : Defines the entry point for the console application.

//

 

#include "stdafx.h"

 

#include "iostream.h" // Needed for cout

#include "fstream.h"  // Needed for ifstream, ofstream

#include "string.h"   // Needed for strlen

#include "stdlib.h"   // Needed for atoi

#include "AVLTree.h"  // AVLClass definition

//

// define non class functions called by main

//

void Usage();                             // display the user commands

void TrimLine(char *iLine);         // Trim whitespace from a line

//

//

// Definitions for main and non class functions

#define MAXLINESIZE 100

//

//

// Global Definitions

//

bool gDebug=false;

 

//****************************************************************************

int main(int argc, char* argv[])

{

      // FUNCTION: int main(int argc, char *argv[])

      //

      // Preconditions: Command line must contain the source file and the

      //          target file

      //

      // PostConditions: none

      //

      // Global vars: none

      //

      // Local vars: XXX

      //

      // Function Calls:

      //

      // Functional Desc:  Verify the command line, open the files,

      //          parse the source file's commands, execute the commands by

      //          calling appropriate functions.

      //

      // Operational Desc: main() first checks the command line to ensure both

      //          a source file and a target file have been specified.

      //          Then the source file and target file are opened, (if either is

      //          unable to be opened main() displays a message and exits).

      //          Each line of the source file is read and parsed.  A switch 

      //          statement controls the selection of the routines to execute

      //          for each of the commands.

      //                Both files are closed implicitly at program exit.

 

      //

      // Verify the command line

      //     

      if ((argc != 3)&& (argc !=4))   //There must be three command line

                        // arguments (Program, SourceFile, TargetFile)

      {

            Usage();    // Display the instruction

            return(1);  // Exit the program

      }

 

      if (argc == 4)

      {

            if (strcmp("DEBUG",argv[3]) ==0)

                  gDebug=true;

 

      }

      //

      // Instantiate the AVL Tree

      //

        AVLTree AVL;

 

 

      //

      //  open the source file

      //

            //   input mode (default)

            //   no create mode (To check for the files existance and not

            //    create it

            //   text mode (default)

 

 

 

      ifstream SourceFile(argv[1],  ios::nocreate);

            //

            // Verify the file is opened

            //

      if (SourceFile.fail() )

      {

            Usage();

            cout << "***************************************" << endl;

            cout << "Unable to open the InputFile: " << argv[1] << endl;

            cout << "***************************************" << endl << endl;

            return(1);        // exit the program

 

 

 

      }

 

      //

      // open the target file

      //

      ofstream TargetFile(argv[2]); // Create the outputfile instantiation

                              // open the output file

                              // Will close when the ofstream class

                              // destructor gets automatically called at the

                              // termination of the program

     

      //

      // Verify the file is opened

      // display error message if the file does not exist

      // (or cannot be written to)

      //

      if(TargetFile.fail())

      {

 

            Usage();

            cout << "***************************************" << endl;

            cout << "Unable to open the  OutputFile: " << argv[2] << endl;

            cout << "***************************************" << endl << endl;

            return(1);        // exit the program

 

 

      }

      AVL.SetFileOut(&TargetFile);

      //

      // Set up the loop conditions

      //

      char LineBuffer[MAXLINESIZE];

      int iKeyValue;

      bool bKeyRead;  // The keyvalue has been read out of the line

      //

      // Start the loop

      //

      while( !SourceFile.eof())

      {

            //

            // Read each line of the Source file

            //

            SourceFile.getline(LineBuffer,sizeof(LineBuffer));

            //

            // clear the white space before and after the line

            // to ensure we don't have any translation problems

            //

            TrimLine(LineBuffer);

            cout << LineBuffer << endl;

            //

            // Parse each line of the Source file

            //

            bKeyRead=(strlen(LineBuffer) >= 3);

                                    // There is a keyvalue on this line

            if (bKeyRead)

                  iKeyValue = atoi(&LineBuffer[2]);

 

            //

            // Save the line in the output file

            //

            TargetFile << LineBuffer << endl;

 

            //

            // Execute the parsed commands in the source file

            //

            switch (LineBuffer[0])

            {

                  case 'A':         //Add the integer to the AVL Tree;

                        if (!bKeyRead) // Ensure there was a keyvalue

                              TargetFile << "Error: No KeyValue Read" << endl;

                        AVL.AddKeyItem(iKeyValue);

                        TargetFile<< AVL.GetStatusMessage()<< endl;

                        break;

 

                  case 'D':         // Delete the Key

                        if (!bKeyRead) // Ensure there was a keyvalue

                              TargetFile << "Error: No KeyValue Read" << endl;

                        AVL.DeleteKeyItem(iKeyValue);

                        TargetFile<< AVL.GetStatusMessage()<< endl;

                        break;

                 

                  case 'S':         // Search the tree

                        if (!bKeyRead) // Ensure there was a keyvalue

                              TargetFile << "Error: No KeyValue Read" << endl;

                        AVL.FindValue(iKeyValue);

                        TargetFile<< AVL.GetStatusMessage()<< endl;

                        break;

 

                  case 'P':         // PreOrder Traversal

                        AVL.PreOrderTraversal(&TargetFile);

                        TargetFile<< AVL.GetStatusMessage()<< endl;

                        break;

                 

                  case 'I':         //InOrder Traversal

                        AVL.InOrderTraversal(&TargetFile);

                        TargetFile<< AVL.GetStatusMessage()<< endl;

                        break;

 

                  case 'R':         // PostOrder traversal

                        AVL.PostOrderTraversal(&TargetFile);

                        TargetFile<< AVL.GetStatusMessage()<< endl;

                        break;

 

 

 

            }

            TargetFile << endl;

 

      } // while( !SourceFile.eof())

 

      //

      // Exitted the loop

      //

 

      //

      // Exit the program

      //

 

      cout << "AVLTrees: Completed" << endl;

     

      return 0;

}

 

//*******************************************************************

void Usage()

{

      // FUNCTION: void Usage()

      //

      // Preconditions: None

      //

      // PostConditions: Program instructions will be printed to the screen.

      //

      // Global vars: none

      //

      // Local vars: none

      //

      // Function Calls: None

      //

      // Functional Desc:  Print Program instructions to the screen.

      //

      // Operational Desc: Print program instructions to the screen.

     

      cout << "AVLTrees " << endl;

      cout << "    Version 1.0.0" << endl << endl;

      cout << "    Usage:   AVLTrees  SourceFile TargetFile [DEBUG]" ;

      cout << endl<< endl;

      cout << "AVLTrees is a wrapper program to test the AVLTree Class" << endl;

      cout << "Programmer: Chuck Scholler" << endl;

 

}

//***********************************************************************

void TrimLine(char *iLine)

{

      // FUNCTION: void TrimLine(char *iLine)

      //

      // Preconditions: iLine contain the line to be trimmed

      //

      // PostConditions: iLine will contain 0 or more characters in the line

      //          with no white space

      //                            Modifies the original line

      // Global vars: none

      //

      // Local vars: int ilength

      //

      // Function Calls: strlen()

      //

      // Functional Desc:  Trim the whitespace at the beginning and end of

      //                            a line

      //

      // Operational Desc: Work back from the end of the line

      //                   moving the end of the line for any

      //                   whitespaces at the end of the line.

      //                            Then find the beginning of the line

      //                   Copy the line to a temp char buffer,

      //                            then copy back to move the line

      //

 

      //

      // Remove the right whitespace first,  this results in a lower

      // copy time for the trim left.

      //

      int ilength = strlen(iLine);

      if (ilength <=0)

            return;

      //

      // ForLoop:

      //  Purpose:  Remove the whitespace at the end of the line

      //  Assertion (Pre):  iLine contains one or more characters to check

      //  Termination :     Exit whenthe first non whitespace character is found

      //

 

      for (int i=ilength-1;i>=0;i--)

      {

            if (iLine[i]!= ' ')           // exit the loop if this is not a space

                  break;

 

            iLine[i]=0;             // shorten the line

      } //  for (int i=ilength-1;i>=0;i--)

 

      //

      // We now have a short string, free of white space on the right

      // Now trim left

      //

     

      // Find the first non white character

      //

      ilength = strlen(iLine);   // may not be the same as before

      if (ilength <=0)              // Already 0 length

            return;

      //

      // Find the beginning of the line

      //

      //

      // ForLoop:

      //  Loop Assertion:  iLine is a char buffer with 0 or more characters in

      //                      it

      //  Loop Termination: (1) Loop will fall through when all characters have

      //                                    been checked and are blank

      //                    (2) Loop will terminate when the first non-white

      //                      space character is found

      for (i=0;i<ilength;i++)

      {

            if (iLine[i] != ' ')

            {

                  //

                  // We have found the beginning of line

                  // Do we have to move the line

                  //

                  if (i == 0)  // no whitespaces to remove

                        return;

                  //

                  // Copy the line then back

                  //

                  char ctemp[MAXLINESIZE];

                  strcpy(ctemp,&iLine[i]);  //copy the line to the temp buffer

                  strcpy(iLine,ctemp);     // copy back to the original

                  return;

                 

            }//if (iLine[i] != ' ')

 

 

      } //for (i=0;i<ilength;i++)

      //

      // If we get here we only had a blank line

      //

       // zero it and return

      //

      iLine[0]=0;

 

}//void TrimLine(char *iLine)