Gen.c
/* GEN.C - Demonstration of data structures, simulating an geneology program
**
** This program demonstrates linked lists, trees, and recursion, to simulate
** a program that would store family geneology information.
**
** Mario Giannini
*/
#include <stdio.h>
#include <stdlib.h>
struct _tagPERSON {
char Name[65];
char Sex;
struct _tagPERSON * Mom, * Dad;
/* Note: the Younger/Older is a linked list of persons */
struct _tagPERSON * SiblingYounger, * SiblingOlder;
struct _tagPERSON * Spouse;
struct _tagPERSON * Children;
struct _tagPERSON * Next; /* Provides easy searching/deleting ability */
};
typedef struct _tagPERSON PERSON;
PERSON * World;
/*** Makes one new PERSON (dynamically), with no relations */
PERSON * CreatePerson( char * Name, int Sex )
{
PERSON * New;
if( (New = calloc(1,sizeof(PERSON))) == NULL )
return(NULL);
strcpy(New->Name,Name);
New->Sex = Sex;
/* Add new person to the world of persons */
New->Next = World;
World = New;
return(New);
}
/**** Marries two persons by connecting them via Spouse pointer */
void Marry( PERSON * Bride, PERSON * Groom )
{
if( Bride->Spouse != NULL || Groom->Spouse!=NULL || Bride==Groom )
printf("Sorry, can't marry %s to %s\n", Bride->Name, Groom->Name );
else
{
Bride->Spouse = Groom;
Groom->Spouse = Bride;
}
}
/**** Creates a new person for a person (and their spouse) **/
PERSON * HasBaby( PERSON * Person, char * Name, int Sex )
{
PERSON * New;
if( (New = CreatePerson(Name,Sex)) == NULL )
return(NULL);
if( Person->Children != NULL ) /* Not first child, add to the list... */
{
New->SiblingOlder = Person->Children;
New->SiblingOlder->SiblingYounger = New; /* My older sibling's younger sibling is me */
}
/* New child appears at head of children list */
Person->Children = New;
Person->Spouse->Children = New;
/* Determine of this person as the Mom or Dad of baby */
New->Mom = Person->Sex=='F' ? Person : Person->Spouse;
New->Dad = Person->Sex=='M' ? Person : Person->Spouse;
return(New);
}
/** Displays person data **/
void ShowPerson( PERSON * Person )
{
PERSON * PersonList;
printf("Stats for %s:\n", Person->Name );
printf("\tMom: %s\n", Person->Mom ? Person->Mom->Name : "N/A" );
printf("\tDad: %s\n", Person->Dad ? Person->Dad->Name : "N/A" );
if( Person->Spouse != NULL )
printf("\tMarried to %s\n", Person->Spouse->Name );
else
printf("\tIs not married\n");
if( Person->SiblingYounger == NULL && Person->SiblingOlder == NULL )
printf("\tHas no siblings\n");
else
{
/* First, go back in the sibling list, to the youngest */
for( PersonList = Person; PersonList->SiblingYounger!=NULL; PersonList = PersonList->SiblingYounger )
;
/* Then list all the siblings, except this person */
for( ; PersonList!=NULL; PersonList = PersonList->SiblingOlder )
if( PersonList != Person )
printf("\tHas a %s named %s\n", PersonList->Sex=='M'?"brother":"sister", PersonList->Name);
}
if( Person->Children == NULL )
printf("\tHas no children\n");
else
{
/* List all the children */
for( PersonList=Person->Children; PersonList!=NULL; PersonList = PersonList->SiblingOlder )
printf("\tHas a %s named %s\n", PersonList->Sex=='M'?"son":"daughter", PersonList->Name);
}
}
/** We can't live forever */
void NukeEm( void )
{
PERSON * PersonList = World, * LastPerson;
while( PersonList )
{
LastPerson = PersonList;
PersonList = PersonList->Next;
printf("About to delete %s\n", LastPerson->Name );
free( LastPerson );
}
}
void main( void )
{
PERSON * Mom, * Dad, * Baby, * BabysHubby, * GrandSon;
Mom = CreatePerson("Edith", 'F' );
Dad = CreatePerson("Archie", 'M' );
Marry( Mom, Dad );
Baby = HasBaby( Mom, "Gloria", 'F' );
HasBaby( Mom, "Bozo", 'M' );
BabysHubby = CreatePerson( "Meathead", 'M' );
Marry( Baby, BabysHubby );
GrandSon = HasBaby( Baby, "Joey", 'M' );
ShowPerson( Baby );
ShowPerson( BabysHubby );
NukeEm( );
}