//========================================================================= //#define PROGRAMMER "BAHN, William" //#define PROG_CODE "bahw" //#define COURSE "ECE-1021" //#define YEAR (2003) //#define TERM "Fall" //#define SECTION (0) //#define ASSIGNMENT "Utility Functions" //#define REVISION (1) //#define TITLE "Linked Lists" //#define SUBTITLE "Last Modified: 28 NOV 03" //#define EMAIL "wbahn@eas.uccs.edu" //#define FILENAME "LinkList.h" //========================================================================= // GENERAL DESCRIPTION // // This file contains functions useful for working with Linked Lists. // REVISION HISTORY // REV 1: 28 NOV 03 // // Added #ifndef directive to prevent multiple inclusions. // REV 0: 09 NOV 03 // // Initial Creation. #ifndef LINKLISTdotH //== INCLUDE FILES ======================================================== #include // printf() #include // gotoxy(), kbhit(), getch() #include // malloc() #include // rand(), RAND_MAX #include "DirtyD.h" //== MACRO DEFINITIONS ==================================================== //== STRUCTURE DEFINITIONS ================================================ //========================================================================= typedef struct LINK LINK; struct LINK { LINK *prev; LINK *next; void *item; }; #define NottaLINK(link) (NULL == (link)) #define IsaLINK(link) (NULL != (link)) //------------------------------------------------------------------------- // LINK functions - primitives LINK *CreateLINK(void); int DestroyLINK(LINK *link); LINK *SetNextLINK(LINK *link, LINK *nextlink); LINK *SetPrevLINK(LINK *link, LINK *prevlink); void *SetLINKItem(LINK *link, void *item); void *GetLINKItem(LINK *link); LINK *GetNextLINK(LINK *link); LINK *GetPrevLINK(LINK *link); //------------------------------------------------------------------------- // LINK functions - manipulatives #define BEFORE (0) #define AFTER (1) LINK *NewLINK(void *item); int IsFirstLINK(LINK *link); int IsLastLINK(LINK *link); LINK *GetFirstLINK(LINK *link); LINK *GetLastLINK(LINK *link); LINK *ConnectLINKs(LINK *first, LINK *second); LINK *InsertLINK(LINK *looselink, int where, LINK *link, void *item); int SwapLINKs(LINK *first, LINK *second); //========================================================================= typedef struct PT PT; struct PT { double x; double y; }; #define NottaPT(pt) (NULL == (pt)) #define IsaPT(pt) (NULL != (pt)) //------------------------------------------------------------------------- // PT functions - primitives PT *CreatePT(void); int DestroyPT(PT *pt); double SetPTx(PT *pt, double x); double SetPTy(PT *pt, double y); double GetPTx(PT *pt); double GetPTy(PT *pt); // PT functions - manipulatives PT *NewPT(double x, double y); PT *RandomPT(double xmin, double xmax, double ymin, double ymax); int IsLessThan(PT *a, PT *b); void Draw(PT *pt, char symbol); //========================================================================= //========================================================================= //========================================================================= // LINK structure functions //========================================================================= //========================================================================= #define NottaLINK(link) (NULL == (link)) //------------------------------------------------------------------------- // LINK functions - primitives //------------------------------------------------------------------------- LINK *CreateLINK(void) { LINK *newLINK; newLINK = (LINK *) malloc(sizeof(LINK)); return(newLINK); } int DestroyLINK(LINK *link) { if(NottaLINK(link)) return(FALSE); if(NULL == GetLINKItem(link)) // Link still has item attached return(FALSE); free(link); return(TRUE); } LINK *SetNextLINK(LINK *link, LINK *nextlink) { link->next = nextlink; return(GetNextLINK(link)); } LINK *SetPrevLINK(LINK *link, LINK *prevlink) { link->prev = prevlink; return(GetPrevLINK(link)); } void *SetLINKItem(LINK *link, void *item) { if(NottaLINK(link)) return(NULL); link->item = item; return(GetLINKItem(link)); } LINK *GetNextLINK(LINK *link) { if(NottaLINK(link)) return(NULL); return(link->next); } LINK *GetPrevLINK(LINK *link) { if(NottaLINK(link)) return(NULL); return(link->prev); } void *GetLINKItem(LINK *link) { if(NottaLINK(link)) return(NULL); return(link->item); } //------------------------------------------------------------------------- // LINK functions - manipulatives //------------------------------------------------------------------------- LINK *NewLINK(void *item) { LINK *newLINK; newLINK = CreateLINK(); SetLINKItem(newLINK, item); SetNextLINK(newLINK, NULL); SetPrevLINK(newLINK, NULL); return(newLINK); } int IsFirstLINK(LINK *link) { if(NottaLINK(link)) return(FALSE); if(NottaLINK(GetPrevLINK(link))) return(TRUE); return(FALSE); } int IsLastLINK(LINK *link) { if(NottaLINK(link)) return(FALSE); if(NottaLINK(GetNextLINK(link))) return(TRUE); return(FALSE); } LINK *GetFirstLINK(LINK *link) { if(NottaLINK(link)) return(NULL); while(!IsFirstLINK(link)) link = GetPrevLINK(link); return(link); } LINK *GetLastLINK(LINK *link) { if(NottaLINK(link)) return(NULL); while(!IsLastLINK(link)) link = GetNextLINK(link); return(link); } LINK *ConnectLINKs(LINK *first, LINK *second) { if( NottaLINK(first) || NottaLINK(second) ) return( NULL ); SetNextLINK(first, second); SetPrevLINK(second, first); return( first ); } LINK *InsertLINK(LINK *looselink, int where, LINK *link, void *item) { if(NottaLINK(link)) return( looselink ); if(NottaLINK(looselink)) return( InsertLINK(NewLINK(item), where, link, NULL )); switch(where) { case BEFORE: ConnectLINKs(GetPrevLINK(link), looselink); ConnectLINKs(looselink, link); break; case AFTER: ConnectLINKs(looselink, GetNextLINK(link)); ConnectLINKs(link, looselink); break; } return(looselink); } int SwapLINKs(LINK *first, LINK *second) { void *temp; if( NottaLINK(first) || NottaLINK(second) ) return(FALSE); temp = GetLINKItem(first); SetLINKItem(first, GetLINKItem(second)); SetLINKItem(second, temp); return(TRUE); } //========================================================================= //========================================================================= // PT structure functions //========================================================================= //========================================================================= //------------------------------------------------------------------------- // PT functions - primitives //------------------------------------------------------------------------- PT *CreatePT(void) { PT *newPT; newPT = (PT *) malloc(sizeof(PT)); SetPTx(newPT, 0.0); SetPTy(newPT, 0.0); return(newPT); } int DestroyPT(PT *pt) { if(NULL == pt) // pt doesn't exist return(FALSE); free(pt); return(TRUE); } double SetPTx(PT *pt, double x) { if(NULL == pt) return(0.0); pt->x = x; return(GetPTx(pt)); } double SetPTy(PT *pt, double y) { if(NULL == pt) return(0.0); pt->y = y; return(GetPTy(pt)); } double GetPTx(PT *pt) { if(NULL == pt) return(0.0); return(pt->x); } double GetPTy(PT *pt) { if(NULL == pt) return(0.0); return(pt->y); } //------------------------------------------------------------------------- // PT functions - manipulatives //------------------------------------------------------------------------- PT *NewPT(double x, double y) { PT *newPT; newPT = CreatePT(); SetPTx(newPT, x); SetPTy(newPT, y); return(newPT); } PT *RandomPT(double xmin, double xmax, double ymin, double ymax) { return(NewPT(rand_fp(xmin, xmax), rand_fp(ymin, ymax))); } int IsLessThan(PT *a, PT *b) { // Primary sort on x-value if(GetPTx(a) < GetPTx(b)) return(TRUE); if(GetPTx(a) > GetPTx(b)) return(FALSE); // x-values equal - Secondary sort on y-value if(GetPTy(a) < GetPTy(b)) return(TRUE); return(FALSE); } void Draw(PT *pt, char symbol) { gotoxy((int) GetPTx(pt), (int) GetPTy(pt)); putch(symbol); return; } #define LINKLISTdotH #endif