Quad tree search skiplists.cc

From Minor Miracle Software
Jump to: navigation, search
 /*
  * Jesse B. Dooley
  * Date: November 1,1999
  * For:  CMSC 420-0201 Fall 1999
  *       Prof. Michelle Hugue
  * Title: Part 2: Minimum Spanning Tree and Nearest Neighbors
  * Module: SlipLists.cpp
  */

#ifndef SKIPLISTS_CPP
#define SKIPLISTS_CPP

#define Levels 10
#define MaxNumberOfLevels (Levels) /* Maximum level of the list (1 more than the number of levels in the list) */
#define MaxLevel (MaxNumberOfLevels-1)

#include <time.h>
#include "site.cc"
#include "List.cc"
#include <string>

class SkipLists {

    struct nodeStructure
    {
        site key;
        nodeStructure* forward[MaxNumberOfLevels]; /* variable sized array of forward pointers */
    };

    nodeStructure header; /* header node */
    int size_int;

    bool IsEven( int i )
    {
        div_t result;
        result = div( i, 2 );
        return (!result.rem );
    } // IsEven

	void initNode( nodeStructure* nS )
    {
        for(int i=0; i< MaxNumberOfLevels; i++)
            nS->forward[i] = NULL;
	}

	short LEVEL( nodeStructure* nS )
    {
    	short Return_short = 0;
        for(int i=0; i< MaxNumberOfLevels; i++)
        	if( nS->forward[i] == NULL )
        		Return_short++;
        return Return_short;
	} // LEVEL

    public:

    SkipLists()
    {
    	size_int = 0;
        initNode( &header );
    }

    SkipLists( const SkipLists &S )
    {
        // copy the nodes
        nodeStructure* q;
        nodeStructure* p = S.header.forward[0];

        while(p != NULL)
        {
            q = p->forward[0];
            insert( p->key ); // just insert the node
            p = q; // advance the pointer
        } // while
    }

    ~SkipLists()
    {
        nodeStructure* q;
        nodeStructure* p = header.forward[0];
        while(p != NULL)
        {
            q = p->forward[0];
            delete p;
            p = q;
        } // while

    	size_int = 0;

        initNode( &header );
    } // ~SkipLists

    bool empty()
    {
        return (header.forward[0] == NULL );
    } // empty

	void erase()
	{
        nodeStructure* q;
        nodeStructure* p = header.forward[0];
        while(p != NULL)
        {
            q = p->forward[0];
            delete p;
            p = q;
        } // while

    	size_int = 0;
        initNode( &header );
	} // erase

    int randomLevel()
    {// return a distribution between 0 and 10

		double Random_double = 0.0;

		time_t L;
		time_t R;
		R = time( &L );

		struct tm* TempTime_p = NULL;
		TempTime_p = localtime( &R );
		Random_double += (double) TempTime_p->tm_sec / rand();
		Random_double += (double) TempTime_p->tm_min / rand();
		Random_double += (double) TempTime_p->tm_hour / rand();
		Random_double += (double) TempTime_p->tm_mday / rand();
		Random_double += (double) TempTime_p->tm_mon / rand();
		Random_double += (double) TempTime_p->tm_year / rand();
		Random_double += (double) TempTime_p->tm_wday / rand();
		Random_double += (double) TempTime_p->tm_yday / rand();
		Random_double += (double) TempTime_p->tm_isdst / rand();
		Random_double *= 1000;
		int Hold = Random_double;
		Random_double -= Hold;

		if( Random_double <= 0.01 )
			return 0;

		if( Random_double <= 0.02 )
			return 1;

		if( Random_double <= 0.06 )
			return 2;

		if( Random_double <= 0.12 )
			return 3;

		if( Random_double <= 0.24 )
			return 4;

		if( Random_double <= 0.48 )
			return 5;

		if( Random_double <= 0.768 )
			return 6;

		if( Random_double <= 0.8192 )
			return 7;

		if( Random_double <= 0.92 )
			return 8;

        return 9;
     } // randomLevel

    void insert( site key) // allows duplicates
    {
        nodeStructure *update[MaxNumberOfLevels]; // hold the preceding pointers
        nodeStructure *p = &header;
        nodeStructure *q = NULL;
        int k = MaxLevel; // which level we are on

        for( int i = 0; i < MaxNumberOfLevels; i++ )
            update[i] = NULL;

		do // find the insertion point
		{
			while( (q = p->forward[k]) && q->key < key)
				p = q;
			update[k] = p;
		} while( --k >= 0 );

        // No duplicates!
        if( q && q->key == key)
        {
            return;
        }

        // create the new node
        k = randomLevel();

		int S = k;
        q = new nodeStructure;

        // initialize the pointer array
        initNode( q );

        q->key = key;

		do
		{
			p = update[k];
			q->forward[k] = p->forward[k];
			p->forward[k] = q;
		} while(--k>=0);

		size_int++;

		cout << " with SkipLists level " << S << endl;
		cout << " Other sites at this level." << endl;
		PRINT_LEVEL( S );
     } // insert

/*
    bool deletenode( site key )
    {
        int k,m;
        nodeStructure* update[MaxLevel];
        nodeStructure* p,q;

        p = &header;
        k = m = level;
        do
        {
            while( (q = p->forward[k]) && (q->key < key) )
                p = q;
            update[k] = p;
        }while( --k >= 0 );

        if( q->key == key)
        {
            for(k=0; k<=m && (p=update[k])->forward[k] == q; k++)
                p->forward[k] = q->forward[k];

            delete q;

            while( header->forward[m] == NULL && m > 0 )
            m--;

            level = m;

			size_int--;
            return(true);
        }
        else
            return(false);
    } // delete
*/

    site* find( site P )
    {
    	return find( P.name() );
    }

    site* find( string name_string )
    {
        nodeStructure *p = &header; // point to the header
        nodeStructure *q = NULL;

        int k = MaxLevel; // which level we are on or MaxLevel

		do while((q = p->forward[k]) && q->key.name() < name_string )
			p = q;
		while( --k >=0 );

        // Found It!
        if( q && q->key.name() == name_string )
        {
            return &q->key;
        }

        return NULL;
    } // search

	int size()
	{
		return size_int;
	} // size

	List<site> GetTypeList( char C )
	{
		List<site> Return_path;
        nodeStructure* p = header.forward[0];

        if( empty() )
			return Return_path;

        while ( p != NULL )
        {
            if( p->key.type() == C )
	        	Return_path.AddToList( p->key );

            p = p->forward[0];
        } // while

		return Return_path;
	} // GetTypeList

	List<site> GetFactoryList( )
	{
		List<site> Return_path;
        nodeStructure* p = header.forward[0];

        if( empty() )
			return Return_path;

        while ( p != NULL )
        {
            if( p->key.type() == 'F' )
	        	Return_path.AddToList( p->key );

            p = p->forward[0];
        } // while

		return Return_path;
	} // GetFactoryList


	void PRINT_LEVEL( short S )
	{
		if( S < 0 || S > MaxLevel )
			return;

        nodeStructure* p = header.forward[S];

        if( empty() )
        {
            cout << "The List is empty." << endl;
            return;
        }

        while ( p != NULL )
        {
            if( p->forward[S] && p->forward[S+1] == NULL )
            {
	            p->key.OutPut();
    	        cout << endl;
			}
            p = p->forward[S];
        } // while
	} // PRINT_LEVEL

    void OutPut()
    {
        nodeStructure* q;
        nodeStructure* p = header.forward[0];

        if( empty() )
        {
            cout << "The List is empty." << endl;
            return;
        }

        while ( p != NULL )
        {
            p->key.OutPut();
            cout << endl;
            q = p->forward[0];
            p = q;
        } // while
    } // OutPut

	List<site> GetResourceList()
	{
		List<site> Return_path;
        nodeStructure* p = header.forward[0];

        if( empty() )
			return Return_path;

        while ( p != NULL )
        {
        	// 'F' is a factory
            if( p->key.type() != 'F' )
	        	Return_path.AddToList( p->key );

            p = p->forward[0];
        } // while

		return Return_path;
	} // GetResourceList

	void SetVisited( string Site_string, bool visited_bool )
	{
		site* S = find( Site_string );

		if( S != NULL )
			S->visited( visited_bool );

	} // GetAdjacentList

	bool WasVisited( string Site_string )
	{
		site* S = find( Site_string );
		if( S != NULL )
			return S->visited();

		return false;
	} // WasVisited

	void SET_VISITED( bool T )
	{
        nodeStructure* p = header.forward[0];

        while ( p != NULL )
        {
            p->key.visited( T );
            p = p->forward[0];
        } // while
	} // ResetVisited

	List<string> getnames()
	{
        nodeStructure* p = header.forward[0];
        List<string> B;

        while ( p != NULL )
        {
            B.AddToList( p->key.name() );
            p = p->forward[0];
        } // while

        return B;
	} // EdgeCount

	void LIST_SITES()
	{
		// Grab the base names first
		// 'L' - lab     |
		// 'B' - barrack | base type
		// 'S' - supply, |

		// 'P' - power   |
		// 'M' - mineral | raw material type

		cout << "List of base sites:" << endl;
		LIST_BASE_SITES();

		cout << "List of raw material sites:" << endl;
		LIST_MATERIAL_SITES();
	}

	void LIST_BASE_SITES()
	{
        nodeStructure* p = header.forward[0];

        while ( p != NULL )
        {
			if( p->key.material() == false )
				p->key.OutPut();
            p = p->forward[0];
        } // while
	}


	void LIST_MATERIAL_SITES()
	{
        nodeStructure* p = header.forward[0];

        while ( p != NULL )
        {
			if( p->key.material() )
				p->key.OutPut();
            p = p->forward[0];
        } // while
	}
}; // SkipLists.cpp
#endif