//================================================================================================== // D a t a _ s t r u c t u r e Interface // B i n a r y _ t r e e // By Bruno Bachelet //================================================================================================== // Copyright (c) 1999-2016 // Bruno Bachelet - bruno@nawouak.net - http://www.nawouak.net // // This file is part of the B++ Library. This library is free software; you can redistribute it // and/or modify it under the terms of the GNU Library General Public License as published by the // Free Software Foundation; either version 2 of the License, or (at your option) any later // version. // // This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; // without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See // the GNU Library General Public License for more details (http://www.gnu.org).
/*DESCRIPTION*/ /* This module provides a binary tree data structure. */
// File Name //------------------------------------------------------------------------------------- #line __LINE__ "data_structure/binary_tree.hpp"
// Guardian //-------------------------------------------------------------------------------------- #ifndef guDataStructureBinaryTree #define guDataStructureBinaryTree
// Headers //--------------------------------------------------------------------------------------- #include <bpp/standard.hpp> /*INCLUDE*/
namespace bpp {
// Importation/Exportation //----------------------------------------------------------------------- #ifdef DATA_STRUCTURE_DLL #define dll_export DLL_EXPORT #else #define dll_export DLL_IMPORT #endif
// Namespaces //------------------------------------------------------------------------------------ #define public_area dataStructureBinaryTree #define private_area dataStructureBinaryTree_private
namespace public_area { /*NAMESPACE*/ using namespace standard; } namespace private_area { using namespace public_area; }
extern_module_name;
// Initialization //-------------------------------------------------------------------------------- #define iniDataStructureBinaryTree has_initializer;
// Macrocommands //--------------------------------------------------------------------------------- /*ALIAS*/ #define tdTree class prData //
/*ALIAS*/ #define tuTree prData //
// Types & Classes //------------------------------------------------------------------------------- namespace public_area { template <tdTree> class clBinaryTree; }
namespace private_area {}
// Functions Interface //--------------------------------------------------------------------------- namespace public_area { template <tdTree> clOutStream & operator << (clOutStream &,const clBinaryTree<tuTree> &); template <tdTree> clInStream & operator >> (clInStream &,clBinaryTree<tuTree> &);
template <tdTree> clOutStream & operator << (clOutStream &, const std_vector(clBinaryTree<tuTree> *) &);
template <tdTree> clInStream & operator >> (clInStream & agStream, std_vector(clBinaryTree<tuTree> *) &); }
namespace private_area { testing_mode ( function void test(void); ) }
// Errors //---------------------------------------------------------------------------------------- namespace public_area { /*ERROR*/ extern_error erEmptyTree; /* The tree is empty. */ }
// Constants & Variables //------------------------------------------------------------------------- extern_static_constant(private,tcString,goNextTreeFlag,?); extern_static_constant(private,tcString,goNodeFlag,?); extern_static_constant(private,tcString,goTreeEndFlag,?); extern_static_constant(private,tcString,goTreeStartFlag,?);
// T r e e Interface //---------------------------------------------------------------------------- namespace public_area { /*CLASS clBinaryTree */ /* Represents the binary tree data structure. */ template <tdTree> class clBinaryTree { //-------------------------------------------------------------------------------------------Types /*TYPE clBinaryTree */ /* This class. */ public_property typedef clBinaryTree<prData> cpTree; //-----------------------------------------------------------------------------------------Private private_property cpTree * atLeft; private_property cpTree * atRight;
private_property void copy(const cpTree &); //------------------------------------------------------------------------------------------Public /*ATTRIBUTE clBinaryTree */ /* Indicates if the tree is empty. */ read_only_attribute(tyBoolean,atEmpty,empty);
/*ATTRIBUTE clBinaryTree */ /* Data contained in the root node of the tree. */ read_only_attribute(prData,atData,data);
public_property constructor clBinaryTree(void); public_property constructor clBinaryTree(const cpTree &); public_property constructor clBinaryTree(const prData &,cpTree * = nil,cpTree * = nil); public_property constructor clBinaryTree(const prData &,const cpTree &,const cpTree &); public_property destructor clBinaryTree(void);
public_property cpTree & operator = (const cpTree &);
public_property cpTree & left(void); public_property const cpTree & left(void) const; public_property cpTree & right(void); public_property const cpTree & right(void) const;
public_property void clear(void); public_property tyCardinal depth(void) const; public_property cpTree & extractLeft(void); public_property cpTree & extractRight(void); public_property void out(clOutStream &) const; public_property void setData(const prData &); public_property void setLeft(cpTree *); public_property void setLeft(const cpTree &); public_property void setRight(cpTree *); public_property void setRight(const cpTree &); public_property tyCardinal size(void) const; public_property tyCardinal width(void) const; }; }
// Functions Inline //------------------------------------------------------------------------------ namespace public_area {} namespace private_area {}
// T r e e Inline //------------------------------------------------------------------------------- namespace public_area { //---------------------------------------------------------------------------------------------Copy template <tdTree> inline void clBinaryTree<tuTree>::copy(const cpTree & agTree) { if (not agTree.atEmpty) { atData=agTree.atData; atLeft=new_object(cpTree(*(agTree.atLeft))); atRight=new_object(cpTree(*(agTree.atRight))); atEmpty=false; } } //--------------------------------------------------------------------------------------Constructor /*METHOD clBinaryTree */ /* Builds an empty tree. */ template <tdTree> inline clBinaryTree<tuTree>::clBinaryTree(void) : atLeft(nil),atRight(nil),atEmpty(true),atData(prData()) {} //--------------------------------------------------------------------------------------Constructor /*METHOD clBinaryTree */ /* Builds a tree by merging two trees. The two trees are not duplicated but directly inserted into the new tree. */ template <tdTree> inline clBinaryTree<tuTree>::clBinaryTree(const prData & agData,cpTree * agLeft,cpTree * agRight) : atLeft(agLeft),atRight(agRight),atEmpty(false),atData(agData) { if (atLeft==nil) atLeft=new_object(cpTree()); if (atRight==nil) atRight=new_object(cpTree()); } //--------------------------------------------------------------------------------------Constructor /*METHOD clBinaryTree */ /* Builds a tree by merging two trees. The two trees are duplicated. */ template <tdTree> inline clBinaryTree<tuTree>::clBinaryTree(const prData & agData,const cpTree & agLeft, const cpTree & agRight) : atLeft(nil),atRight(nil),atEmpty(false),atData(agData) { atLeft=new_object(cpTree(agLeft)); atRight=new_object(cpTree(agRight)); } //---------------------------------------------------------------------------------------Operator = /*METHOD clBinaryTree */ /* Copies a tree. */ template <tdTree> inline clBinaryTree<tuTree> & clBinaryTree<tuTree>::operator = (const cpTree & agTree) { clear(); copy(agTree); return (*this); } //---------------------------------------------------------------------------------------------Left /*METHOD clBinaryTree */ /* Returns the left branch of the tree. Read-write version. */ template <tdTree> inline clBinaryTree<tuTree> & clBinaryTree<tuTree>::left(void) { if (atEmpty) send_inline_error(erEmptyTree,"tree::left"); return (*atLeft); } //---------------------------------------------------------------------------------------------Left /*METHOD clBinaryTree */ /* Returns the left branch of the tree. Read-only version. */ template <tdTree> inline const clBinaryTree<tuTree> & clBinaryTree<tuTree>::left(void) const { if (atEmpty) send_inline_error(erEmptyTree,"tree::left"); return (*atLeft); } //--------------------------------------------------------------------------------------------Right /*METHOD clBinaryTree */ /* Returns the right branch of the tree. Read-write version. */ template <tdTree> inline clBinaryTree<tuTree> & clBinaryTree<tuTree>::right(void) { if (atEmpty) send_inline_error(erEmptyTree,"tree::right"); return (*atRight); } //--------------------------------------------------------------------------------------------Right /*METHOD clBinaryTree */ /* Returns the right branch of the tree. Read-only version. */ template <tdTree> inline const clBinaryTree<tuTree> & clBinaryTree<tuTree>::right(void) const { if (atEmpty) send_inline_error(erEmptyTree,"tree::right"); return (*atRight); } //--------------------------------------------------------------------------------------------Clear /*METHOD clBinaryTree */ /* Empties the tree. */ template <tdTree> inline void clBinaryTree<tuTree>::clear(void) { if (not atEmpty) { delete_object(atLeft); delete_object(atRight); atLeft=nil; atRight=nil; atEmpty=true; } } //--------------------------------------------------------------------------------------ExtractLeft /*METHOD clBinaryTree */ /* Extracts the left branch of the tree. */ template <tdTree> inline clBinaryTree<tuTree> & clBinaryTree<tuTree>::extractLeft(void) { cpTree * lcLeft;
if (atEmpty) send_inline_error(erEmptyTree,"tree::extractLeft"); lcLeft=atLeft; atLeft=new_object(cpTree()); return (*lcLeft); } //-------------------------------------------------------------------------------------ExtractRight /*METHOD clBinaryTree */ /* Extracts the right branch of the tree. */ template <tdTree> inline clBinaryTree<tuTree> & clBinaryTree<tuTree>::extractRight(void) { cpTree * lcRight;
if (atEmpty) send_inline_error(erEmptyTree,"tree::extractRight"); lcRight=atRight; atRight=new_object(cpTree()); return (*lcRight); } //------------------------------------------------------------------------------------------SetData /*METHOD clBinaryTree */ /* Sets the data contained in the root node of the tree. */ template <tdTree> inline void clBinaryTree<tuTree>::setData(const prData & agData) { if (atEmpty) { atLeft=new_object(cpTree()); atRight=new_object(cpTree()); atEmpty=false; }
atData=agData; } //------------------------------------------------------------------------------------------SetLeft /*METHOD clBinaryTree */ /* Sets the left branch of the tree. The given branch is not duplicated but directly inserted in the tree. The old branch is destructed. */ template <tdTree> inline void clBinaryTree<tuTree>::setLeft(cpTree * agTree) { if (atEmpty) send_inline_error(erEmptyTree,"tree::setLeft"); delete_object(atLeft);
if (agTree==nil) atLeft=new_object(cpTree()); else atLeft=agTree; } //------------------------------------------------------------------------------------------SetLeft /*METHOD clBinaryTree */ /* Sets the left branch of the tree. The given branch is duplicated. The old branch is destructed. */ template <tdTree> inline void clBinaryTree<tuTree>::setLeft(const cpTree & agTree) { if (atEmpty) send_inline_error(erEmptyTree,"tree::setLeft"); *atLeft=agTree; } //-----------------------------------------------------------------------------------------SetRight /*METHOD clBinaryTree */ /* Sets the right branch of the tree. The given branch is not duplicated but directly inserted in the tree. The old branch is destructed. */ template <tdTree> inline void clBinaryTree<tuTree>::setRight(cpTree * agTree) { if (atEmpty) send_inline_error(erEmptyTree,"tree::setRight"); delete_object(atRight);
if (agTree==nil) atRight=new_object(cpTree()); else atRight=agTree; } //-----------------------------------------------------------------------------------------SetRight /*METHOD clBinaryTree */ /* Sets the right branch of the tree. The given branch is duplicated. The old branch is destructed. */ template <tdTree> inline void clBinaryTree<tuTree>::setRight(const cpTree & agTree) { if (atEmpty) send_inline_error(erEmptyTree,"tree::setRight"); *atRight=agTree; } }
// Functions Implementation //---------------------------------------------------------------------- namespace public_area { //---------------------------------------------------------------------------------Tree Operator << /*FUNCTION*/ /* Writes a tree into a stream. */ template <tdTree> clOutStream & operator << (clOutStream & agStream,const clBinaryTree<tuTree> & agTree) { agStream << private_area::goTreeStartFlag << end_line;
if (not agTree.empty()) { agStream << private_area::goNodeFlag << " = "; agStream << standard::string((tyBoolean)(not agTree.left().empty())); agStream << " , " << standard::string((tyBoolean)(not agTree.right().empty())); agStream << " ; "; agTree.data().out(agStream); agStream << end_line;
if (not agTree.left().empty()) agTree.left().out(agStream); if (not agTree.right().empty()) agTree.right().out(agStream); }
agStream << private_area::goTreeEndFlag << end_line; return (agStream); } //---------------------------------------------------------------------------------Tree Operator >> /*FUNCTION*/ /* Reads a tree from a stream. */ template <tdTree> clInStream & operator >> (clInStream & agStream,clBinaryTree<tuTree> & agTree) { method_name("tree::operator >>");
typedef clBinaryTree<tuTree> cpTree;
tyBoolean lcLeft; tyBoolean lcRight; clString lcString;
tyBoolean lcFirst = false;
agStream >> lcString;
if (lcString==private_area::goTreeStartFlag) { agStream >> lcString; agTree.clear(); lcFirst=true; }
if (lcString!=private_area::goTreeEndFlag) { if (lcString!=private_area::goNodeFlag) send_error(erStreamReading); agStream >> lcString >> lcString; lcLeft=boolean(lcString.data()); agStream >> lcString >> lcString; lcRight=boolean(lcString.data()); agStream >> lcString;
agTree.setData(prData(agStream)); agTree.setLeft(new_object(cpTree())); agTree.setRight(new_object(cpTree())); if (lcLeft) agStream >> agTree.left(); if (lcRight) agStream >> agTree.right();
if (lcFirst) { agStream >> lcString; if (lcString!=private_area::goTreeEndFlag) send_error(erStreamReading); } }
return (agStream); } //-------------------------------------------------------------------------Vector(Tree) Operator << /*FUNCTION*/ /* Writes a vector of trees into a stream. */ template <tdTree> clOutStream & operator << (clOutStream & agStream, const std_vector(clBinaryTree<tuTree> *) & agTreeS) { tyCardinal lcCounter = 0;
while (lcCounter<agTreeS.size()) { agStream << *(agTreeS[lcCounter]); ++lcCounter;
if (lcCounter<agTreeS.size()) agStream << end_line << private_area::goNextTreeFlag << end_line << end_line; }
return (agStream); } //-------------------------------------------------------------------------Vector(Tree) Operator >> /*FUNCTION*/ /* Reads a vector of trees from a stream. */ template <tdTree> clInStream & operator >> (clInStream & agStream, std_vector(clBinaryTree<tuTree> *) & agTreeS) { method_name("std_vector(tree *)::operator >>");
clString lcString;
do { agTreeS.push_back(new_object(clBinaryTree<tuTree>)); agStream >> *(agTreeS.back()); agStream >> lcString; } while (lcString==private_area::goNextTreeFlag);
if (lcString!="") send_error(erStreamReading); return (agStream); } }
namespace private_area {}
// T r e e Implementation //----------------------------------------------------------------------- namespace public_area { //--------------------------------------------------------------------------------------Constructor /*METHOD clBinaryTree */ /* Builds a tree by copying another one. */ template <tdTree> clBinaryTree<tuTree>::clBinaryTree(const cpTree & agTree) : atLeft(nil),atRight(nil),atEmpty(true),atData(prData()) { clear(); copy(agTree); } //---------------------------------------------------------------------------------------Destructor /*METHOD clBinaryTree */ /* Destructs the tree. */ template <tdTree> clBinaryTree<tuTree>::~clBinaryTree(void) { if (not atEmpty) { delete_object(atLeft); delete_object(atRight); } } //--------------------------------------------------------------------------------------------Depth /*METHOD clBinaryTree */ /* Returns the depth of the tree. A null depth means the tree is empty. */ template <tdTree> tyCardinal clBinaryTree<tuTree>::depth(void) const { if (atEmpty) return (0); return (maxi(atLeft->depth(),atRight->depth()) + 1); } //----------------------------------------------------------------------------------------------Out /*METHOD clBinaryTree */ /* Writes the tree into a stream. */ template <tdTree> void clBinaryTree<tuTree>::out(clOutStream & agStream) const { if (not atEmpty) { agStream << "node = "; agStream << standard::string(tyBoolean(not atLeft->atEmpty)); agStream << " , " << standard::string(tyBoolean(not atRight->atEmpty)); agStream << " ; "; atData.out(agStream); agStream << end_line;
if (not atLeft->atEmpty) atLeft->out(agStream); if (not atRight->atEmpty) atRight->out(agStream); } } //---------------------------------------------------------------------------------------------Size /*METHOD clBinaryTree */ /* Returns the number of nodes in the tree. */ template <tdTree> tyCardinal clBinaryTree<tuTree>::size(void) const { if (atEmpty) return (0); return (atLeft->size()+atRight->size()+1); } //--------------------------------------------------------------------------------------------Width /*METHOD clBinaryTree */ /* Returns the width of the tree. A null width means the tree is empty. */ template <tdTree> tyCardinal clBinaryTree<tuTree>::width(void) const { if (atEmpty) return (0); return (1+atLeft->width()+atRight->width()); } }
// End //------------------------------------------------------------------------------------------- } #undef dll_export #undef tdTree #undef tuTree #undef public_area #undef private_area #endif |
//================================================================================================== // D a t a _ s t r u c t u r e Implementation // B i n a r y _ t r e e // By Bruno Bachelet //================================================================================================== // Copyright (c) 1999-2016 // Bruno Bachelet - bruno@nawouak.net - http://www.nawouak.net // // This file is part of the B++ Library. This library is free software; you can redistribute it // and/or modify it under the terms of the GNU Library General Public License as published by the // Free Software Foundation; either version 2 of the License, or (at your option) any later // version. // // This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; // without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See // the GNU Library General Public License for more details (http://www.gnu.org).
// File Name //------------------------------------------------------------------------------------- #line __LINE__ "data_structure/binary_tree.cpp"
// DLL Belonging //--------------------------------------------------------------------------------- #define DATA_STRUCTURE_DLL
// Headers //--------------------------------------------------------------------------------------- #include <bpp/data_structure/binary_tree.hpp> /*INTERFACE*/
namespace bpp {
// Namespaces //------------------------------------------------------------------------------------ #define public_area dataStructureBinaryTree #define private_area dataStructureBinaryTree_private #define dll_export DLL_EXPORT
namespace public_area {} namespace private_area {}
static_module_name("Data_structure/Binary_tree");
// Initialization //-------------------------------------------------------------------------------- #undef iniDataStructureBinaryTree static_constant(private_area::clInitializer,goInitializer);
// Errors //---------------------------------------------------------------------------------------- namespace public_area { static_error erEmptyTree; }
// Constants & Variables //------------------------------------------------------------------------- static_constant(tcString,goNextTreeFlag); static_constant(tcString,goNodeFlag); static_constant(tcString,goTreeEndFlag); static_constant(tcString,goTreeStartFlag);
// Static Members //-------------------------------------------------------------------------------- namespace public_area {} namespace private_area {}
// Functions Implementation //---------------------------------------------------------------------- namespace public_area {} namespace private_area {}
// X X X Implementation //------------------------------------------------------------------------- namespace {}
// I n i t i a l i z e r Implementation //--------------------------------------------------------- namespace private_area { //--------------------------------------------------------------------------------------------Start property void clInitializer::start(void) { if (atCounter++ == 0) { try { #include <bpp/modules.hpp> /*NEED*/ registerStop(this); environment::informInitialization(goModuleName);
erEmptyTree.create("Data Structure - The tree is empty.");
goNextTreeFlag = "<and>"; goNodeFlag = "node"; goTreeEndFlag = "<tree_end>"; goTreeStartFlag = "<tree_start>"; }
initializer_catch; } } //---------------------------------------------------------------------------------------------Stop property void clInitializer::stop(void) { environment::informTermination(goModuleName); } }
// End //------------------------------------------------------------------------------------------- } |
|