GIDForums  

Go Back   GIDForums > Computer Programming Forums > C++ Forum
User Name
Password
Register FAQ Members List Calendar Search Today's Posts Mark Forums Read

 
 
Thread Tools Search this Thread Rate Thread
  #1  
Old 04-Dec-2007, 00:47
crazy_ivan crazy_ivan is offline
New Member
 
Join Date: Sep 2007
Posts: 7
crazy_ivan is on a distinguished road

Binary search tree help


Hi all, I am writing a program that takes an input specified by two iterators, creates a binary search tree, and then prints out the values by an inorder traversal. So far, I have the following:

CPP / C++ / C Code:
//treesort.h
//header file for treesort fnc

#include<iostream>
#include <iterator>

#ifndef FILE_TREESORT_H_INCLUDED
#define FILE_TREESORT_H_INCLUDED

template <typename T>

struct node
{
	T data;
	node *left;
	node *right;

	//node ctor
	node(T item)
	{
		data = item;
		left = NULL;
		right = NULL;
	}

	~node()
	{
		delete left;
		delete right;
	}
};

//insert fnc
template <typename T>
void insert(node<T> *&root, T newItem)
{
	if(root == NULL)
	{
		root = new node<T>(newItem);
		return;
	}

	else if(newItem < root->data)
	{
		insert(root->left, newItem);
	}
	else
	{
		insert(root->right, newItem);
	}
}

//postOrderPrint fnc
//prints tree in post-order
template <typename T, typename FDIter>
void traverse (node<T> *root, FDIter iter)
{
	if(root != NULL)
	{
		traverse(root->left, iter);
		*iter++ = root->data;
		traverse(root->right, iter);
	}
}

//treesort fnc
template <typename FDIter>
void treesort(FDIter first, FDIter last)
{
	typedef typename std::iterator_traits<FDIter>::value_type ValueType;
	node<ValueType> *root;
	root = NULL;
	int ctr = 0;
	try
	{
		for (FDIter it = first; it != last; ++it)
		{
			insert(root, *first);
		}
		traverse(root, first);

	}
	
	catch(...)
	{
		delete root;
		throw;
	}
	delete root;
}


#endif;

Everything seems like it should work fine; I tested this without the iterators and it worked perfectly, but when I run this with a test program provided by our professor, it tells me that I fail the sorting test. I conclude that I am messing up something with the iterators...but I can't for the life of me figure out what that is. Can anyone help me out?

The test program that I am given to work with. This is a .cpp file; my file is a template header only.
CPP / C++ / C Code:
// treesort_test.cpp


#include "treesort.h"   // For treesort
// Include above BEFORE system files, to make sure it works by itself
#include "treesort.h"   // Double inclusion test

// Includes for testing package
#include <iostream>     // for std::cout, std::endl
#include <string>       // for std::string

// Includes for this testing program
#include <vector>       // for std::vector
#include <list>         // for std::list
#include <deque>        // for std::deque
#include <algorithm>    // for std::stable_sort, std::equal

// ************************************************************************
// Testing class
// ************************************************************************


// class Tester
// For extremely simple unit testing.
// Keeps track of number of tests and number of passes.
// Use test (with success/failure parameter) to do a test.
// Get results with numTests, numPassed, numFailed, allPassed.
// Restart testing with reset.
// Invariants:
//     countTests_ == number of tests (calls to test) since last reset.
//     countPasses_ == number of times function test called with true param
//      since last reset.
//     0 <= countPasses_ <= countTests_.
//     tolerance_ >= 0.
class Tester {

// ***** Tester: ctors, dctor, op= *****
public:

    // Default ctor
    // Sets countTests_, countPasses_ to zero, tolerance_ to given value
    // Pre: None.
    // Post:
    //     numTests == 0, countPasses == 0, tolerance_ == abs(theTolerance)
    Tester(double theTolerance = 0.0000001)
        :countTests_(0),
         countPasses_(0),
         tolerance_(theTolerance >= 0 ? theTolerance : -theTolerance)
    {}

    // Compiler-generated copy ctor, copy op=, dctor are used

// ***** Tester: general public functions *****
public:

    // test
    // Handles single test, param indicates pass/fail
    // Pre: None.
    // Post:
    //     countTests_ incremented
    //     countPasses_ incremented if (success)
    //     Message indicating test name (if given)
    //      and pass/fail printed to cout
    void test(bool success,
              const std::string & testName = "")
    {
        ++countTests_;
        if (success) ++countPasses_;

        std::cout << "    ";
        if (testName != "")
        {
            std::cout << "Test: "
                      << testName
                      << " - ";
        }
        std::cout << (success ? "passed" : "********** FAILED **********")
                  << std::endl;
    }

    // ftest
    // Does single floating-point test.
    // Tests passes iff difference of first two values is <= tolerance.
    // Pre: None.
    // Post:
    //     countTests_ incremented
    //     countPasses_ incremented if (abs(val1-val2) <= tolerance_)
    //     Message indicating test name (if given)
    //      and pass/fail printed to cout
    void ftest(double val1,
               double val2,
               const std::string & testName = "")
    { test(val1-val2 <= tolerance_ && val2-val1 <= tolerance_, testName); }

    // reset
    // Resets *this to default constructed state
    // Pre: None.
    // Post:
    //     countTests_ == 0, countPasses_ == 0
    void reset()
    {
        countTests_ = 0;
        countPasses_ = 0;
    }

    // numTests
    // Returns the number of tests that have been done since last reset 
    // Pre: None.
    // Post:
    //     return == countTests_
    int numTests() const
    { return countTests_; }

    // numPassed
    // Returns the number of tests that have passed since last reset
    // Pre: None.
    // Post:
    //     return == countPasses_
    int numPassed() const
    { return countPasses_; }

    // numFailed
    // Returns the number of tests that have not passed since last reset
    // Pre: None.
    // Post:
    //     return + countPasses_ == numTests_
    int numFailed() const
    { return countTests_ - countPasses_; }

    // allPassed
    // Returns true if all tests since last reset have passed
    // Pre: None.
    // Post:
    //     return == (countPasses_ == countTests_)
    bool allPassed() const
    { return countPasses_ == countTests_; }

    // setTolerance
    // Sets tolerance_ to given value
    // Pre: None.
    // Post:
    //     tolerance_ = abs(theTolerance)
    void setTolerance(double theTolerance)
    { tolerance_ = (theTolerance >= 0 ? theTolerance : -theTolerance); }

// ***** Tester: data members *****
private:

    int countTests_;    // Number of tests done since last reset
    int countPasses_;   // Number of tests passed since last reset
    double tolerance_;  // Tolerance for floating-point near-equality tests

};  // end class Tester


// ************************************************************************
// Class for type requirements checking
// ************************************************************************

// class OnlyLessThan
// For objects with limited operator availability.
// Has only default ctor, big 3, and operator< (always returns false).
// In particular, does not have operators ==, !=, >, >=.
// Invariants: None.
class OnlyLessThan {

    // Compiler-generated default ctor, copy ctor, copy =, dctor used

};  // End class OnlyLessThan

// operator< (OnlyLessThan)
// Fake operator< for OnlyLessThan class
// Returns false - which is legal, if all objects of type OnlyLessThan
// represent the same numeric value.
// Pre: None.
// Post:
//     Return is false.
// Does not throw (No-Throw Guarantee)
bool operator<(const OnlyLessThan & a,
               const OnlyLessThan & b)
{ return false; }


// ************************************************************************
// Item class for checking number of existing objects
// ************************************************************************


// class Counter
// Item type for counting number of existing objects and operations
// performed.
// Invariants:
//     Counter::exist_ is number of objects of type Counter
//      that currently exist.
//     Counter::maxExist_ is max number of objects of type Counter
//      that have ever existing at one time, since last call to
//      Counter::reset or start of program.
//     Counter::ops_ is total number of calls to Counter default ctor,
//      copy ctor, copy assignment, dctor, since last call to
//      Counter::reset or start of program.
class Counter {

// ***** Counter: Ctors, dctor, op= *****
public:

    // Default ctor
    // Pre: None.
    // Post: None.
    Counter()
    {
        ++exist_;
        if (exist_ > maxExist_)
            maxExist_ = exist_; 
        ++ops_;
    }

    // Copy ctor
    // Pre: None.
    // Post: None.
    Counter(const Counter & other)
    {
        ++exist_;
        if (exist_ > maxExist_)
            maxExist_ = exist_; 
        ++ops_;
    }

    // Copy assignment
    // Pre: None.
    // Post: None.
    Counter & operator=(const Counter & rhs)
    {
        ++ops_;
        return *this;
    }

    // Dctor
    // Pre: None.
    // Post: None.
    ~Counter()
    {
        --exist_;
        ++ops_;
    }

// ***** Counter: General public functions *****
public:

    static void reset()
    {
        maxExist_ = exist_;
        ops_ = 0;
    }

    // getExisting
    // Returns value of exist_
    // Pre: None.
    // Post:
    //     Return value == exist_.
    static int getExisting()
    { return exist_; }

    // getMaxExisting
    // Returns value of maxExist_
    // Pre: None.
    // Post:
    //     Return value == maxExist_.
    static int getMaxExisting()
    { return maxExist_; }

    // getOps
    // Returns value of ops_
    // Pre: None.
    // Post:
    //     Return value == ops_.
    static int getOps()
    { return ops_; }

// ***** Counter: Data members *****
private:

    static int exist_;     // # of existing objects
    static int maxExist_;  // Max # of existing objects since last reset
    static int ops_;       // # of operations performed so far

};  // End class Counter

// Definition of static data members of class Counter
int Counter::exist_ = 0;
int Counter::maxExist_ = 0;
int Counter::ops_ = 0;

bool operator<(const Counter & a,
               const Counter & b)
{ return false; }


// ************************************************************************
// Special "pair" item class
// ************************************************************************


// class MyPair
// Holds pair of ints
// operator== is as usual, operator< only compairs first item in each pair
// Invariants: None.
class MyPair {

public:

    MyPair(int theX = 0,
           int theY = 0)
        :x_(theX),
         y_(theY)
    {}

    // Compiler-generated copy ctor, copy =, dctor used

    // getX
    // returns x_
    // Pre: None.
    // Post:
    //     Return value == x_.
    // Does not throw (No-Throw Guarantee)
    int getX() const
    { return x_; }

    // getY
    // returns y_
    // Pre: None.
    // Post:
    //     Return value == y_.
    // Does not throw (No-Throw Guarantee)
    int getY() const
    { return y_; }

private:

    int x_;  // First item in pair
    int y_;  // Second item in pair

};  // End class MyPair


bool operator==(const MyPair & a,
                const MyPair & b)
{ return a.getX() == b.getX() && a.getY() == b.getY(); }

bool operator<(const MyPair & a,
               const MyPair & b)
{ return a.getX() < b.getX(); }


// ************************************************************************
// Test Suite Functions
// ************************************************************************


// test_treesort_type_requirements
// Test suite for function treesort, type requirements
// Pre: None.
// Post:
//     Pass/fail status of tests have been registered with t.
//     Appropriate have been messages printed to cout.
// Does not throw (No-Throw Guarantee)
void test_treesort_type_requirements(Tester & t)
{
    std::cout << "Test Suite: function treesort, type requirements" << std::endl;

    // Works with minimal-functionality type (passes if it compiles)
    std::vector<OnlyLessThan> v(100);
    treesort(v.begin(), v.end());
    t.test(true, "Compiles with value type having minimal functionality");
}


// test_treesort_basic_int
// Test suite for function treesort, basic functionality, sorting ints
// Pre: None.
// Post:
//     Pass/fail status of tests have been registered with t.
//     Appropriate have been messages printed to cout.
// Does not throw (No-Throw Guarantee)
void test_treesort_basic_int(Tester & t)
{
    std::cout << "Test Suite: function treesort, basic functionality - sorting ints" << std::endl;

    // Value type for this test suite
    typedef int val;

    const int DATASIZE = 20;
    val data[DATASIZE] = { 3, 6, 19, -2, 8, 6, 7, 1, 141, -2, -200, 4, 6, 6, 11, -5, 32, 2, 7, 0 };
    // Make copies of data
    const std::vector<val> dataCheck(data, data+DATASIZE);
    std::vector<val> data_v(data, data+DATASIZE);
    std::deque<val> data_d(data, data+DATASIZE);
    std::list<val> data_l(data, data+DATASIZE);

    // Sorted data (all but first, last)
    std::vector<val> dataSorted1(data, data+DATASIZE);
    std::stable_sort(dataSorted1.begin()+1, dataSorted1.end()-1);

    // Sorted data (all)
    std::vector<val> dataSorted2(data, data+DATASIZE);
    std::stable_sort(dataSorted2.begin(), dataSorted2.end());

    // Test: vector empty range
    treesort(data_v.begin()+7, data_v.begin()+7);
    t.test(std::equal(data_v.begin(), data_v.end(), dataCheck.begin()), "vector: empty range");

    // Test: vector one item
    treesort(data_v.begin()+7, data_v.begin()+8);
    t.test(std::equal(data_v.begin(), data_v.end(), dataCheck.begin()), "vector: one item");

    // Test: vector nearly all
    treesort(data_v.begin()+1, data_v.end()-1);
    t.test(std::equal(data_v.begin(), data_v.end(), dataSorted1.begin()), "vector: nearly all");

    // Test: vector all
    treesort(data_v.begin(), data_v.end());
    t.test(std::equal(data_v.begin(), data_v.end(), dataSorted2.begin()), "vector: all");

    // Test: deque empty range
    treesort(data_d.begin()+7, data_d.begin()+7);
    t.test(std::equal(data_d.begin(), data_d.end(), dataCheck.begin()), "deque: empty range");

    // Test: deque one item
    treesort(data_d.begin()+7, data_d.begin()+8);
    t.test(std::equal(data_d.begin(), data_d.end(), dataCheck.begin()), "deque: one item");

    // Test: deque nearly all
    treesort(data_d.begin()+1, data_d.end()-1);
    t.test(std::equal(data_d.begin(), data_d.end(), dataSorted1.begin()), "deque: nearly all");

    // Test: deque all
    treesort(data_d.begin(), data_d.end());
    t.test(std::equal(data_d.begin(), data_d.end(), dataSorted2.begin()), "deque: all");

    std::list<val>::iterator it1, it2;

    // Test: list empty range
    it1 = data_l.begin();
    std::advance(it1, 3);
    it2 = data_l.begin();
    std::advance(it2, 3);
    treesort(it1, it2);
    t.test(std::equal(data_l.begin(), data_l.end(), dataCheck.begin()), "list: empty range");

    // Test: list one item
    ++it2;
    treesort(it1, it2);
    t.test(std::equal(data_l.begin(), data_l.end(), dataCheck.begin()), "list: one item");

    // Test: list nearly all
    it1 = data_l.begin();
    ++it1;
    it2 = data_l.end();
    --it2;
    treesort(it1, it2);
    t.test(std::equal(data_l.begin(), data_l.end(), dataSorted1.begin()), "list: nearly all");

    // Test: list all
    treesort(data_l.begin(), data_l.end());
    t.test(std::equal(data_l.begin(), data_l.end(), dataSorted2.begin()), "list: all");
}


// test_treesort_basic_double
// Test suite for function treesort, basic functionality, sorting doubles
// Pre: None.
// Post:
//     Pass/fail status of tests have been registered with t.
//     Appropriate have been messages printed to cout.
// Does not throw (No-Throw Guarantee)
void test_treesort_basic_double(Tester & t)
{
    std::cout << "Test Suite: function treesort, basic functionality - sorting doubles" << std::endl;

    // Value type for this test suite
    typedef double val;

    const int DATASIZE = 20;
    val data[DATASIZE] = { 3.1, 6.2, 19.3, -2.4, 8.5, 6.6, 7.7, 1.8, 141.9, -2.0, -200.1, 4.2, 6.3, 6.4, 11.5, -5.6, 32.7, 2.8, 7.9, 0.0 };
    // Make copies of data
    const std::vector<val> dataCheck(data, data+DATASIZE);
    std::vector<val> data_v(data, data+DATASIZE);
    std::deque<val> data_d(data, data+DATASIZE);
    std::list<val> data_l(data, data+DATASIZE);

    // Sorted data (all but first, last)
    std::vector<val> dataSorted1(data, data+DATASIZE);
    std::stable_sort(dataSorted1.begin()+1, dataSorted1.end()-1);

    // Sorted data (all)
    std::vector<val> dataSorted2(data, data+DATASIZE);
    std::stable_sort(dataSorted2.begin(), dataSorted2.end());

    // Test: vector empty range
    treesort(data_v.begin()+7, data_v.begin()+7);
    t.test(std::equal(data_v.begin(), data_v.end(), dataCheck.begin()), "vector: empty range");

    // Test: vector one item
    treesort(data_v.begin()+7, data_v.begin()+8);
    t.test(std::equal(data_v.begin(), data_v.end(), dataCheck.begin()), "vector: one item");

    // Test: vector nearly all
    treesort(data_v.begin()+1, data_v.end()-1);
    t.test(std::equal(data_v.begin(), data_v.end(), dataSorted1.begin()), "vector: nearly all");

    // Test: vector all
    treesort(data_v.begin(), data_v.end());
    t.test(std::equal(data_v.begin(), data_v.end(), dataSorted2.begin()), "vector: all");

    // Test: deque empty range
    treesort(data_d.begin()+7, data_d.begin()+7);
    t.test(std::equal(data_d.begin(), data_d.end(), dataCheck.begin()), "deque: empty range");

    // Test: deque one item
    treesort(data_d.begin()+7, data_d.begin()+8);
    t.test(std::equal(data_d.begin(), data_d.end(), dataCheck.begin()), "deque: one item");

    // Test: deque nearly all
    treesort(data_d.begin()+1, data_d.end()-1);
    t.test(std::equal(data_d.begin(), data_d.end(), dataSorted1.begin()), "deque: nearly all");

    // Test: deque all
    treesort(data_d.begin(), data_d.end());
    t.test(std::equal(data_d.begin(), data_d.end(), dataSorted2.begin()), "deque: all");

    std::list<val>::iterator it1, it2;

    // Test: list empty range
    it1 = data_l.begin();
    std::advance(it1, 3);
    it2 = data_l.begin();
    std::advance(it2, 3);
    treesort(it1, it2);
    t.test(std::equal(data_l.begin(), data_l.end(), dataCheck.begin()), "list: empty range");

    // Test: list one item
    ++it2;
    treesort(it1, it2);
    t.test(std::equal(data_l.begin(), data_l.end(), dataCheck.begin()), "list: one item");

    // Test: list nearly all
    it1 = data_l.begin();
    ++it1;
    it2 = data_l.end();
    --it2;
    treesort(it1, it2);
    t.test(std::equal(data_l.begin(), data_l.end(), dataSorted1.begin()), "list: nearly all");

    // Test: list all
    treesort(data_l.begin(), data_l.end());
    t.test(std::equal(data_l.begin(), data_l.end(), dataSorted2.begin()), "list: all");
}


// test_treesort_object_count
// Test suite for function treesort, object counts
// Pre: None.
// Post:
//     Pass/fail status of tests have been registered with t.
//     Appropriate have been messages printed to cout.
// Does not throw (No-Throw Guarantee)
void test_treesort_object_count(Tester & t)
{
    std::cout << "Test Suite: function treesort, object counts" << std::endl;

    const int SIZE = 100;
    std::vector<Counter> vc(SIZE);
    Counter::reset();

    treesort(vc.begin(), vc.end());
    t.test(Counter::getMaxExisting() >= 2*SIZE, "at least n additional objects used in sorting");
    t.test(Counter::getExisting() == SIZE, "all additional objects destroyed");

}


// test_treesort_stability
// Test suite for function treesort, stability
// Pre: None.
// Post:
//     Pass/fail status of tests have been registered with t.
//     Appropriate have been messages printed to cout.
// Does not throw (No-Throw Guarantee)
void test_treesort_stability(Tester & t)
{
    std::cout << "Test Suite: function treesort, stability" << std::endl;

    const int SIZE = 16;

    int dataX[SIZE] = { 8, 7, 7, 6, 2, 3, 2, 4, 8, 3, 1, 1, 4, 5, 6, 5 };
    int dataY[SIZE] = { 1, 1, 2, 1, 1, 1, 2, 1, 2, 2, 1, 2, 2, 1, 2, 2 };

    std::vector<MyPair> vp1(SIZE);
    for (int i = 0; i < SIZE; ++i)
        vp1[i] = MyPair(dataX[i], dataY[i]);

    std::vector<MyPair> vp2(vp1);

    treesort(vp1.begin(), vp1.end());
    std::stable_sort(vp2.begin(), vp2.end());
    t.test(std::equal(vp1.begin(), vp1.end(), vp2.begin()), "treesort is stable");
}


// test_treesort
// Test suite for function treesort
// Uses other test-suite functions
// Pre: None.
// Post:
//     Pass/fail status of tests have been registered with t.
//     Appropriate have been messages printed to cout.
// Does not throw (No-Throw Guarantee)
void test_treesort(Tester & t)
{
    // Do all the test suites
    std::cout << "TEST SUITES FOR FUNCTION treesort" << std::endl;
    test_treesort_type_requirements(t);
    test_treesort_basic_int(t);
    test_treesort_basic_double(t);
    test_treesort_object_count(t);
    test_treesort_stability(t);
}


// ************************************************************************
// Main program
// ************************************************************************


// main
// Runs function treesort test suite, prints results to cout.
int main()
{
    Tester t;
    test_treesort(t);

    std::cout << std::endl;
    if (t.allPassed())
    {
        std::cout << "All tests successful" 
                  << std::endl;
    }
    else
    {
        std::cout << "Tests ********** UNSUCCESSFUL **********"
                  << std::endl;
    }
    std::cout << std::endl;
}


Last edited by LuciWiz : 04-Dec-2007 at 11:45. Reason: Please insert your C/C++ code between [cpp] & [/cpp] tags
 
 

Recent GIDBlogA Week in Kuwait by crystalattice

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Deleting a node from binary search tree earachefl C++ Forum 3 28-Jun-2006 07:26
can anyone help me with my tree :) bioeng_mtm C++ Forum 5 22-Apr-2006 12:50
Binary Search Tree in C++ rpg3 C++ Forum 5 02-Apr-2006 09:53
printing binary search tree nkhambal C Programming Language 2 26-Mar-2005 03:01
Search Engine Positioning 101 and 201 "How To" Tips... 000 Search Engine Optimization Forum 0 29-May-2003 10:34

Network Sites: GIDNetwork · GIDWebHosts · GIDSearch · Learning Journal by J de Silva, The

All times are GMT -6. The time now is 16:19.


vBulletin, Copyright © 2000 - 2008, Jelsoft Enterprises Ltd.