Here we have added push_front, push_back, isort, and we have also separated out into a function the task of creating a newNode ... so that now we may code Node* n = newNode(); This becomes important when we want to use the insert_sorted function to isort (insertion sort) an unsorted list.
3. Here, with added push_front, push_back and insertion sort of an unsorted list ...
/* ListOfStringInsertSorted_readLine_ver3.c */
#include "readLine.h" /* also includes, stdio.h, stdlib.h, string.h,
myAssert( .. ) and newCopy( .. ) */
typedef struct myNode
{
char* str; /* 'str' holds the address of a new C string */
struct myNode* next; /* points to the next C string ... */
} Node;
typedef struct myList /* to hold (data for) a List ... */
{
Node* front;
Node* back;
int size;
int isSorted; /* NEW here compared to previous version */
} List;
Node* newNode()
{
Node* n = (Node*) malloc( sizeof( Node ));
myAssert( ( n != NULL ), "ERROR! malloc failed in 'createNode'" );
n->next = NULL;
return n;
}
/* prototypes ... */
/* INSERTS into 'list' in 'ABC...abc...' order the CString 's' */
void init( List* );
void insert_sorted( List*, Node* );
void isort( List* ); /* NEW here ... */
void push_front( List*, Node* ); /* NEW here ... */
void push_back( List*, Node* ); /* NEW here ... */
void clear( List* ); /* erase/free up all memory in list */
void show( List* ); /* show all 'text lines' in the 'list' */
int main() /* * * * * * * * * * * * * * MAIN BEGINS * * * * * * * * * * * * * */
{
char* s;
Node* n;
List list;
init( &list );
puts( "Enter line of text to push_front in your list ('Ctrl Z' to end) ..." );
fputs( "> ", stdout );
while( (s = readLine( stdin )) ) /* i.e. while s != NULL */
{
n = newNode();
n->str = s;
push_front( &list, n );
fputs( "> ", stdout );
}
puts( "\nYour list now is ..." );
show( &list );
isort( &list );
puts( "\nAfter isort ... show( &list ) is ..." );
show( &list );
printf( "\nEnter an other line to insert > " ); fflush( stdout );
s = readLine( stdin );
n = newNode();
n->str = s;
insert_sorted( &list, n );
puts( "\nYour list now is:" );
show( &list );
clear( &list ); /* Note: re-sets list to NULL */
puts( "\nAfter clear( &list ) ... your list now is:" );
show( &list );
printf( "\nPress 'Enter' ... to continue ... " );
getchar();
return 0;
}/* * * * * * * * * * * * * * * * * * MAIN ENDS * * * * * * * * * * * * * * * */
void init( List* list )
{
list->front = list->back = NULL;
list->size = 0;
list->isSorted = 1;
}
/* passing in the address (a reference) of both the 'List' and the 'Node' */
void insert_sorted( List* list, Node* n )
{
Node* head = list->front;
/* firstly, we handle most common case where 'n' is NOT the first Node */
if( head != NULL && strcmp( n->str, head->str ) >= 0 ) /* NEED >= */
{
/* so search the linked list for the right location */
Node* cur = head;
while( cur->next != NULL && strcmp( cur->next->str, n->str ) <= 0 )
{
cur = cur->next;
}
if( cur == list->back ) list->back = n;
n->next = cur->next;
cur->next = n;
/* list->front = head; // unchanged */
++ list->size;
}
else /* apparently this IS the first node ... */
{
n->next = head; /* set this node in first position, head could be NULL */
list->front = n;
++ list->size;
if( list->size == 1 ) list->back = n;
}
}
void isort( List* list )
{
Node* cur,
* nextNode;
List nList;
init( &nList );
for( cur = list->front; cur != NULL; cur = nextNode )
{
nextNode = cur->next; /* get a copy of 'next' before changed below ... */
insert_sorted( &nList, cur );
}
/* now ... update old list with new front and back ... */
list->front = nList.front;
list->back = nList.back;
list->isSorted = 1;
/* size hasn't changed */
}
void push_front( List* list, Node* n )
{
n->next = list->front; /* make old front 2nd positon in list, old=NULL is ok */
list->front = n; /* update front ...*/
++ list->size;
if( list->size == 1 ) list->back = n;
if( list->size > 1 ) list->isSorted = 0;
}
void push_back( List* list, Node* n )
{
n->next = NULL; /* to signal that the end of the list is reached */
if( list->size > 0 )list->back->next = n; /* place at end */
else list->front = n;
list->back = n; /* update back ...*/
++ list->size;
if( list->size > 1 ) list->isSorted = 0;
}
void clear( List* list )
{
Node* head = list->front;
while( head != NULL )
{
Node* nextNode = head->next;
free( head->str );
free( head );
head = nextNode;
}
list->size = 0;
list->isSorted = 1;
list->front = list->back = NULL ;
}
void show( List* list ) /* Note: 'head' is a 'local copy' of the pointer */
{
if( list->size )
{
Node* head = list->front;
int i;
for( i = 0; head != NULL; head = head->next, ++i )
printf( "list (%d): %s\n", i+1, head->str ); /* note added '\n' at str end */
printf( "size = %d\n", list->size );
}
else puts( "'Your list is empty'" );
}
(Note: all 3 header files, readLine.h, myClist.h and myNode.h follow this ...ver.4 test program)
4. And finally ... adding msort (merge sort) ... and having now 2 more header files beside readLine.h ... ready to re-use ...
/* ListOfStringInsertSorted_ver4.c */ /* 2011-03-27 */
#include "myNode.h" /* also includes readLine.h that includes ...
stdio.h, stdlib.h, string.h and has
myAssert( .. ) and newCopy( .. )
also includes myClist.h
myNode.h also has msort, isortClist, insert_sortedClist
*/
int main() /* * * * * * * * * * * * * * MAIN BEGINS * * * * * * * * * * * * * */
{
char* s;
Node* n;
Clist list;
initClist( &list );
puts( "Enter lines of text to push_back into list ('Ctrl Z' to end) ..." );
fputs( "> ", stdout ); fflush( stdout );
while( (s = readLine( stdin )) ) /* i.e. while s != NULL */
{
n = newNode(); /* get new memory for this node ... */
n->str = s;
push_backClist( &list, n );
fputs( "> ", stdout ); fflush( stdout );
}
puts( "\nYour list now is ..." );
showClist( &list );
msort( &list );
puts( "\nASfter msort ... your list now is ..." );
showClist( &list );
printf( "\nEnter a line to insert in sorted order > " ); fflush( stdout );
n = newNode();
n->str = readLine( stdin );
insert_sortedClist( &list, n );
puts( "\nYour list now is:" );
showClist( &list );
clearClist( &list ); /* Note: re-sets list to NULL */
puts( "\nAfter clearClist( &list ) ... your list now is:" );
showClist( &list );
puts( "Enter lines of text to push_front into list ('Ctrl Z' to end) ..." );
fputs( "> ", stdout ); fflush( stdout );
while( (s = readLine( stdin )) ) /* i.e. while s != NULL */
{
n = newNode(); /* get new memory for this node ... */
n->str = s;
push_frontClist( &list, n );
fputs( "> ", stdout ); fflush( stdout );
}
puts( "\nYour list now is:" );
showClist( &list );
printf( "\nEnter a line to insert in sorted order > " ); fflush( stdout );
n = newNode();
n->str = readLine( stdin );
insert_sortedClist( &list, n );
puts( "\nYour list now is:" );
showClist( &list );
clearClist( &list ); /* Note: re-sets list to NULL */
puts( "\nAfter clearClist( &list ) ... your list now is:" );
showClist( &list );
printf( "\nPress 'Enter' to continue/exit ... " ); fflush( stdout );
getchar();
return 0;
}/* * * * * * * * * * * * * * * * * * MAIN ENDS * * * * * * * * * * * * * * * */