/* File: list2.c Implementation of an ordered linked list ADT */ #include #include #include "string.h" #include "list2.h" /* Private Function Prototypes */ static void CrashOnNull(void *, char *) ; static node *NewNode(char *) ; static void FreeNode(node *ptr) ; /* Private Function Implementations */ /* Exit if ptr is NULL. */ static void CrashOnNull(void *ptr, char *mesg) { if (ptr == NULL) { fprintf(stderr, "%s\n", mesg) ; exit(1) ; } } /* Make a new node with given item and next field set to NULL */ static node *NewNode(char *item) { node *new ; new = (node *) malloc (sizeof(node)) ; CrashOnNull(new, "cannot make new node") ; if (item == NULL) item = "" ; new->item = strdup(item) ; CrashOnNull(new->item, "cannot duplicate string") ; new->next = NULL ; return new ; } /* Free memory allocated to the node */ static void FreeNode(node *ptr) { if (ptr->item != NULL) free(ptr->item) ; free(ptr) ; } /* Add an item to the sorted list */ void AddItem (list L, char *item) { node *prev, *new ; new = NewNode(item) ; prev = &L->header ; while (prev->next != NULL && strcmp(prev->next->item, item) < 0) { prev = prev->next ; } new->next = prev->next ; prev->next = new ; L->count++ ; if (new->next == NULL) L->last = new ; } /* Does item with key appear on the ordered list? 0=No 1=Yes */ int IsMember2(list L, char *key) { node *current ; int r ; current = L->header.next ; while(current != NULL) { r = strcmp(current->item, key) ; if (r == 0) return 1 ; if (r > 0) return 0 ; current = current->next ; } return 0 ; } /* Return the position in the ordered list of an item with key or NULL if no such item. The position is a pointer to the node prior to the item with the key. */ node *Search (list L, char *key) { node *prev ; int r ; prev = &L->header ; while(prev->next != NULL) { r = strcmp(prev->next->item, key) ; if (r == 0) return prev ; if (r > 0) return NULL ; prev = prev->next ; } return NULL ; } /* Merge list L2 into list L1, removing duplicates. L2 is destroyed. */ void MergeList(list L1, list L2) { node *prev1, *current2, *temp ; int r ; prev1 = &L1->header ; current2 = L2->header.next ; L1->count += L2->count ; while (prev1->next != NULL && current2 != NULL) { r = strcmp(prev1->next->item, current2->item) ; if (r > 0) { /* Found right place to insert current L2 item */ temp = current2 ; current2 = current2->next ; temp->next = prev1->next ; prev1->next = temp ; prev1 = temp ; } else if (r < 0) { /* next L1 item smaller than current L2 item */ prev1 = prev1->next ; } else { /* found duplicate L1 and L2 item */ temp = current2 ; current2 = current2->next ; FreeNode(temp) ; L1->count-- ; } } /* Add remaining items from L2 if any */ if (prev1->next == NULL && current2 != NULL) { prev1->next = current2 ; L1->last = L2->last ; } free(L2) ; }