#include "list.h" ////////////////////////////////////////////////////////////////////// // // append() - add newNode to the list after place // List *append(List *theList, Node *place, Node *newNode) { ////////////////////////////////////////////////////////////////// // // tmp will be our "after" pointer, allowing the side of the list // to the right of place to connect in to newNode // Node *tmp = NULL; ////////////////////////////////////////////////////////////////// // // edge case: should the list pointer be NULL, allocate a new List // and initialize theList -> start and end to sane // initial values. This is essentially what mklist() // does in the sll projects. // if (theList == NULL) { theList = (List *) malloc(sizeof(List)); theList -> start = NULL; theList -> end = NULL; } ////////////////////////////////////////////////////////////////// // // edge case: the only thing that can gum up the works now is a // NULL newNode; so if one is encountered, do nothing // and return the list as-is. // if (newNode != NULL) { ////////////////////////////////////////////////////////////// // // edge case: if we have an empty list, newNode becomes the // list contents. // if ((theList -> start == NULL) && (theList -> end == NULL)) { ////////////////////////////////////////////////////////////// // // this is the simplest case- nothing exists so newNode IS // the list contents. Merely update the start and end // pointers and we're all set. // theList -> start = newNode; theList -> end = newNode; } ////////////////////////////////////////////////////////////// // // edge case: if we're appending after end, we need to take // care to update theList -> end // else if (place == theList -> end) { ////////////////////////////////////////////////////////////// // // this is the next simplest case to connect, as we only have // to deal with one connection (hooking newNode into the list; // then update theList -> end as appropriate). // newNode -> prev = theList -> end; theList -> end = newNode; } ////////////////////////////////////////////////////////////// // // average case: if we're dealing with a typical append, we // do the following. We're also protecting // against a rogue edge case of the list being // non-empty yet place being NULL (trying to // process that condition would result in // certain disaster). // else if (place != NULL) { ////////////////////////////////////////////////////////////// // // positioning tmp: we can only navigate from the end of the // list, so we must start tmp there; then, // keep seeking until we arrive at the node // one prev away from place. // tmp = theList -> end; while (tmp -> prev != place) { tmp = tmp -> prev; } ////////////////////////////////////////////////////////////// // // connecting it: newNode connects to place, and the existing // list node connecting to place hooks to // newNode. // newNode -> prev = place; tmp -> prev = newNode; } } ////////////////////////////////////////////////////////////////// // // whether we modify the list or bail out, we'll always return // the right thing. // return(theList); }