Click here to Skip to main content
15,892,005 members
Articles / Desktop Programming / MFC

Tree Container Library

Rate me:
Please Sign up or sign in to vote.
4.85/5 (29 votes)
22 Aug 2007Zlib10 min read 229.6K   7.2K   111  
A generic template class library for storing data in a tree-like structure.
//#include "stdafx.h"
#include <string>
#include <iostream>
#include <sstream>
#include "unique_tree.h"

// forward declaration
class cRental;

namespace utility
{
	void populate_tree(unique_tree<cRental>& rental_tree);
	void print_tree(const unique_tree<cRental>& rental_tree, const int depth);
	bool is_last_child(const unique_tree<cRental>* node);
}

class cRental
{
public:
	cRental() : rental_no(0) {}
	cRental(const int rental_no_) : rental_no(rental_no_) {}
	cRental(const int rental_no_, const std::string& rental_name_)
		: rental_no(rental_no_), rental_name(rental_name_) {}
	virtual ~cRental() {}

	virtual std::string get_rental_type() const { return "unknown"; }
	virtual cRental* clone() const { return new cRental(*this); }

	friend bool operator < (const cRental& lhs, const cRental& rhs) { return lhs.rental_no < rhs.rental_no; }
	int get_rental_no() const { return rental_no; }
	const std::string& get_name() const { return rental_name; }
	std::string print() const
	{
		std::ostringstream ostr;
		ostr << get_rental_type() << ": " << get_name();
		return ostr.str();
	}

private:
	int rental_no;
	std::string rental_name;
};

class cProperty : public cRental
{
public:
	cProperty() : acreage(0.0), land_value(0.0) {}
	cProperty(	int rental_no_, 
				const std::string& property_name_,
				double acreage_,
				double land_value_)
				:	cRental(rental_no_, property_name_),
					acreage(acreage_),
					land_value(land_value_)  {}
	virtual ~cProperty() {}

	virtual std::string get_rental_type() const { return "Property"; }
	virtual cRental* clone() const { return new cProperty(*this); }

private:
	double acreage;
	double land_value;
};

class cBuilding : public cRental
{
public:
	cBuilding()  {}
	cBuilding(	int rental_no_, 
				const std::string& building_name_,
				const std::string& address_)
				:	cRental(rental_no_, building_name_),
					address(address_)  {}
	virtual ~cBuilding() {}

	virtual std::string get_rental_type() const { return "Building"; }
	virtual cRental* clone() const { return new cBuilding(*this); }

private:
	std::string address;
};

class cUnit : public cRental
{
public:
	cUnit() : rent_amt(0.0) {}
	cUnit(	int rental_no_, 
				const std::string& unit_name_,
				double rent_amt_)
				:	cRental(rental_no_, unit_name_),
					rent_amt(rent_amt_)  {}
	~cUnit() {}

	virtual std::string get_rental_type() const { return "Unit"; }
	virtual cRental* clone() const { return new cUnit(*this); }

private:
	double rent_amt;
	std::string unit_code;
};

cRental* clone_fcn(const cRental& rental_obj)
{
	return rental_obj.clone();
}

int main(int argc, char* argv[])
{
	unique_tree<cRental> rental_tree(cRental(0, "My Properties"));
	

	// populate and print tree without supplying clone function
	std::cout << "Tree without clone function" << std::endl << std::endl;
	utility::populate_tree(rental_tree);
	utility::print_tree(rental_tree, 0);
	std::cout << std::endl << std::endl << std::endl;

	// populate and print tree supplying a clone function
	std::cout << "Tree with clone function" << std::endl << std::endl;
	rental_tree.clear();
	rental_tree.set_clone(&clone_fcn);
	utility::populate_tree(rental_tree);
	utility::print_tree(rental_tree, 0);
	std::cout << std::endl << std::endl;

	return 0;
}

void utility::populate_tree(unique_tree<cRental>& rental_tree)
{
	// insert properties
	rental_tree.insert( cRental(0), cProperty(100, "Riverside Property", 35.5, 1000.00));
	rental_tree.insert( 0, cProperty(200, "Main Street Property", 21.6, 2500.00));
	rental_tree.insert( 0, cProperty(300, "Boston Ave Property", 52.1, 4300.00));

	// insert buildings
	rental_tree.insert( 100, cBuilding(110, "Tech Building", "4636 Riverside Road" ));
	rental_tree.insert( 100, cBuilding(120, "Riverside Hotel", "4690 Riverside Road"));

	rental_tree.insert( 200, cBuilding(210, "Main Street Building", "322 Main Street"));

	rental_tree.insert( 300, cBuilding(310, "Boston Ave Tech Center", "3200 Boston Ave"));
	rental_tree.insert( 300, cBuilding(320, "Mike's Pool Hall", "3350 Boston Ave"));
	rental_tree.insert( 300, cBuilding(330, "Porter Apartment Bldg", "3300 Boston Ave"));

	// insert units
	rental_tree.insert( 110, cUnit(111, "Suite G1", 1400.00));
	rental_tree.insert( 110, cUnit(112, "Suite G2", 2150.00));
	rental_tree.insert( 110, cUnit(113, "Suite G3", 1530.00));
	rental_tree.insert( 110, cUnit(114, "Suite G4", 2300.00));
	rental_tree.insert( 110, cUnit(115, "Suite G5", 2640.00));

	rental_tree.insert( 120, cUnit(121, "Room 1A", 600.00));
	rental_tree.insert( 120, cUnit(122, "Room 1B", 550.00));
	rental_tree.insert( 120, cUnit(123, "Room 1C", 650.00));
	rental_tree.insert( 120, cUnit(124, "Room 2A", 700.00));
	rental_tree.insert( 120, cUnit(125, "Room 2B", 630.00));
	rental_tree.insert( 120, cUnit(126, "Room 2C", 800.00));

	rental_tree.insert( 210, cUnit(211, "Apt 1", 550.00));
	rental_tree.insert( 210, cUnit(212, "Apt 2", 600.00));
	rental_tree.insert( 210, cUnit(213, "Apt 3", 730.00));
	rental_tree.insert( 210, cUnit(214, "Apt 4", 660.00));

	rental_tree.insert( 310, cUnit(311, "Suite A", 2200.00));
	rental_tree.insert( 310, cUnit(312, "Suite B", 1900.00));
	rental_tree.insert( 310, cUnit(313, "Suite C", 2500.00));

	rental_tree.insert( 330, cUnit(331, "Apt 101", 900.00));
	rental_tree.insert( 330, cUnit(332, "Apt 102", 680.00));
	rental_tree.insert( 330, cUnit(333, "Apt 103", 800.00));
	rental_tree.insert( 330, cUnit(334, "Apt 201", 880.00));
	rental_tree.insert( 330, cUnit(335, "Apt 202", 930.00));
}

void utility::print_tree(const unique_tree<cRental>& rental_tree, const int depth )
{
	std::cout << rental_tree.get()->print() << std::endl;

	unique_tree<cRental>::const_iterator it = rental_tree.begin(), it_end = rental_tree.end();
	for ( ; it != it_end; ++it ) {
		for ( int i = 0; i < depth; ++i ) {
			const unique_tree<cRental>* parent = &rental_tree;
			for ( int j = depth - 1; j > i; --j )
				parent = parent->parent();

			std::cout <<  (is_last_child(parent) ? " " : "|");

			std::cout << std::string(2, ' ');
		}
		std::cout << "|" << std::endl;
		std::cout << std::string(depth * 3 + 1, ' ') << "- ";
		print_tree(*it.node(), depth + 1);
	}
}

bool utility::is_last_child(const unique_tree<cRental>* node)
{
	const unique_tree<cRental>* parent = node->parent();
	unique_tree<cRental>::const_iterator it = parent->end();
	--it;
	return it->get_rental_no() == node->get()->get_rental_no();
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The zlib/libpng License



Comments and Discussions