/**
 * Program Filename: Lab12e2.cpp
 * Authur: ZHU, Xiaoqing
 * Created: 4/11/98
 * Modified:
 * Description:
 * This program creates linked list, it reads data from file and then
 * at the end it deletes list.
 *
 * In this program we will insert each node into the list according the
 * alphabetical order of each people's last name, this will require
 * string comparation and traversing of the list, also the program will
 * show you how to insert a node into the middle of the list.
 */
#include <iostream.h>
#include <fstream.h>
#include <string.h>
/**
 * the input file
 */
#define INPUT_FILE "a:list.in"
/**
 * constant
 * the maximum length of names
 */
const int MAXNAME = 16;
/**
 * structure People
 * stores information of a person with his/her name, id and age
 */
struct People
{
	char fname[MAXNAME];
	char lname[MAXNAME];
	int  id;
	int  age;
};
/**
 * the linklist node type
 * another structure that has People as its data field and
 * next as its link field
 *
 * using this approach we can change the content of the data field
 * without modifying linklist operation
 */
struct Node
{
	People people;
	Node  *next;
};
/**
 * Function prototypes
 */
Node* readList( Node* ); // read a list from the input file
Node* readNode( ifstream& ); // read a node from the input file
/* new! */
Node* addToListInOrder( Node*, Node* ); // add a node to the list, revised
/* new! */
Node* findPosition( Node*, Node* ); // search for insert position
/* new! */
Node* insertAfter( Node*, Node*, Node* ); // insert a node after another
Node* deleteList( Node* ); // delete all the nodes in the list
void  printList( Node* ); // print the whole list
void  printPeople( People& ); // print one people
void  Wait(); // prompt user to press any key to continue...
/**
 * main program begins
 */
int main()
{
	Node *PeopleList = NULL;
lab12-1.gif (1433 bytes)
	// now we read the list from the pre_defined input file
	PeopleList = readList( PeopleList );

// Now call readList


/**
 * Function: readList
 * Description: Reads the data from a file and calls function readPeople
 *     will create list and put those data read from the file in the list
 * Parameters: list - the linked list header pointer
 * Returns: the linked list with data
 */
Node* readList( Node *list )
{
	ifstream cinf;
	Node *newNode = NULL;
	cinf.open( INPUT_FILE );
	// read data now
	while ( (newNode = readNode(cinf)) != NULL ) {

// Now call readNode - this is the same as before - so just show results

lab12-7.gif (3404 bytes)

		list = addToListInOrder( list, newNode );

// Now call new function addToListInOrder


/**
 * Function: addToListInOrder
 * Description: Creates linked list with data that is passed to it 
 * Params: list - the linked list header pointer
 *         newNode - a pointer to the new node
 * Returns: new header pointer
 */
Node* addToListInOrder( Node *list, Node *newnode )
{
	Node *prev = NULL;
lab12p2-1.gif (4892 bytes)
	prev = findPosition( list, newnode );

// Now call findPosition


/**
 * Function: findPosition new!
 * Description: This function will search the list for the last persion
 *    record in the list that is "smaller" than the new node, then
 *    it will return a pointer to this node. If the first node is "bigger"
 *    than the new one, a NULL pointer is returned; If every
 *    node is "smaller" a pointer to the last node is returned.
 * Params: list - the header pointer of the list
 *         newNode - pointer to the new node
 * Returns: a pointer to the previous node of insert position
 */
Node *findPosition( Node *list, Node *newNode )
{
	Node *prev=NULL, *current=list;
lab12p2-2.gif (5408 bytes)
// while the current people is "no bigger than" the new people...
  while ( current!=NULL ) {
    if ( strcmp( current->people.lname, newNode->people.lname ) > 0 )
      return prev;
    else {
      prev = current;
      current = prev->next;
    }
  }
  return prev;
}

// Now return to addToListInOrder


 

Node* addToListInOrder( Node *list, Node *newnode )
{
	Node *prev = NULL;
	prev = findPosition( list, newnode );

lab12p2-1.gif (4892 bytes)

	list = insertAfter( list, prev, newnode );

// Now call insertAfter


 

/**
 * Function: insertAfter new!
 * Description: This function will insert the new node into the linked 
 *    list after the node specified
 * Params: list - the header pointer
 *         prev - pointer to the node that we'll insert the new one after
 *         newNode - pointer to the new node
 * Returns: the new header pointer
 */
Node* insertAfter( Node *list, Node *prev, Node *newnode )
{
lab12p2-3.gif (4380 bytes)
	if ( prev == NULL ) {
		newnode->next = list;
		list = newnode;
	} else {
		newnode->next = prev->next;
		prev->next = newnode;
	}
lab12p2-4.gif (4558 bytes)
	return list;
}

// Now return to addToListInOrder, which returns to ReadList

lab12p2-5.gif (2973 bytes)
// Now execute the loop again and reads another node

lab12p2-6.gif (3660 bytes)

// Now call addToListInOrder the second time

 

Node* addToListInOrder( Node *list, Node *newnode )
{
	Node *prev = NULL;
	prev = findPosition( list, newnode );

// now call findPosition the second time


Node *findPosition( Node *list, Node *newNode )
{
	Node *prev=NULL, *current=list;
lab12p2-7.gif (6966 bytes)
	// while the current poeple is "no bigger than" the new people...
	while ( current!=NULL ) {
		if ( strcmp( current->people.lname, newNode->people.lname ) > 0 )
			return prev;
		else {
			prev = current;
			current = prev->next;
		}
	}
	return prev;
}

// Now return to addToListInOrder and call insert After


Node* insertAfter( Node *list, Node *prev, Node *newnode )
{
lab12p2-8.gif (5082 bytes)
	if ( prev == NULL ) {
		newnode->next = list;
		list = newnode;
	} else {
		newnode->next = prev->next;
		prev->next = newnode;
	}
lab12p2-9.gif (5558 bytes)
	return list;
}

//Now return to addToListInOrder which returns to readList

lab12p2-10.gif (4459 bytes)

// Now call ReadNode the third time to give

lab12p2-11.gif (4726 bytes)

//Now call addToListInOrder the third time
// which calls findPosition the third time

 

Node *findPosition( Node *list, Node *newNode )
{
	Node *prev=NULL, *current=list;
lab12p2-12.gif (7990 bytes)
	// while the current poeple is "no bigger than" the new people...
	while ( current!=NULL ) {
		if ( strcmp( current->people.lname, newNode->people.lname ) > 0 )
			return prev;
		else {
			prev = current;
			current = prev->next;
		}
	}
lab12p2-13.gif (8531 bytes)
	return prev;
}

//Now return to addToListInOrder and call InsertAfter


 

Node* insertAfter( Node *list, Node *prev, Node *newnode )
{
lab12p2-14.gif (6987 bytes)
	if ( prev == NULL ) {
		newnode->next = list;
		list = newnode;
	} else {
		newnode->next = prev->next;
		prev->next = newnode;
	}
lab12p2-15.gif (6940 bytes)
	return list;
}

//Now return to addToListInOrder and then ReadList

lab12p2-16.gif (5039 bytes)

// Since this is end of file - the next call to readNode will cause readList to break out of while loop
// and return to main function with

lab12p2-17.gif (4766 bytes)

NOTICE: the input is now in alphabetical order!!