stammbaum

S

soso

Jungspund
Hallo!

Wir müssen gerade ein Programm schreiben, was einen Familienstammbaum verwalten soll...

Es soll Personen hinzufügen, löschen, namen ändern,.... können

Außerdem soll es, wenn zwei namen gegeben werden, sagen können, in welcher verwandschaftlichen beziehung diese zueinander stehen....

alle familienmitglieder sind übrigens in einer datei aufgelistet... (darin stehen die name, das geschlecht, eine Identifikationsnummer und die Id der Eltern...)...

leider haben wir keine ahnung, wie man bäume in c implementiert oder wie man mit diesen umgehen kann...?(

hat irgendjemand eine ahnung, wo man diese info bekommt???

wir wissen nicht wie wir anfangen sollen.... keine ahnung wie der aufbau sein könnte...;(

vielen dank
gruß
 
Warum in C?

Für solche Sachen ist SWI-Prolog wie geschaffen.
 
Ein Baum selbst besteht wieder aus Teilbäumen. In Java würd ich das ganze in etwa so machen (nur als Anhalt):
Code:
public class Tree<T>{ 
    private Tree<T> left; 
    private Tree<T> right; 
    private T node; 
     
    public Tree(T node){ 
        this.node=node; 
    }   
}

Da C (C++ wird ja dann auch genauso unrelevant sein, wie Prolog/Java) keine Klassen hat, würd ich eine entsprechende struct bauen...
 
mal wieder nicht aufgepasst in der uni wa?
 
Ein binärer Baum würde so aussehen:
Code:
typedef struct P_NODE *T_NODE;

typedef struct T_NODE {
	char* content;
	P_BLOCK lChild;
	P_BLOCK rChild;
} T_NODE;
Musst du noch für deine Zwecke anpassen.
 
Wenn man das schon in C machen soll, warum nicht gleich die Standard-Library-Funktionen verwenden anstatt das Rad neu zu erfinden? Dafür gibts doch auf so ziemlich allem, was sich "UNIX" oder so ähnlich nennt, tsearch(), tfind(), etc. Die Manual-Page (tsearch(3)) sollte sogar ein Beispielprogramm enthalten, das die Verwendung relativ anschaulich zeigt.

Gruesse
 
Bei der Abfrage von Familienbeziehungen ist der Binärbaum sicherlich das kleinste Problem... ;) Vor allem braucht Ihr den eigentlich in der Forum nicht; eine
Code:
typedef struct _persiom {
	struct person* p_mutter;
	struct person* p_vater;
	struct person* p_gatte;
	
	int geschlecht;
	char * name;
} person;
reicht ja. Mir fällt bei der Ermittlung der Verwandschaftsbeziehung nichts Besseres ein, als brutal alles, was man unter http://de.wikipedia.org/wiki/Verwandtschaftsbeziehung findet, Generation für Generation durchzutesten. Fies wird's bei eden höhergradigen Beziehungen. Und interessant werden auch Abstammungen bei geschiedenen Ehepartnern wie Halbbruder und -schwester. Dazu müsste dann struct person* p_gatte; zu struct person** p_gatten; werden und eine Feldsuche durchgeführt werden.

Ich halte die Aufgabe für sehr umfangreich...
 
Zuletzt bearbeitet:
Hallo!

vielen dank erstmal für die bisherigen antworten!!
hat uns inspiriert...

im folgenden mal unser programm... es ist sicherlich viel zu lang und viel zu umständlich implementiert, aber besser können wir es nicht :think:

leider geht es auch nich... :D unsere main is schonmal falsch... denn es wird nur unser printf-text ausgegeben... selbst wenn wir die richtigen kommandzeilenopperatoren eingeben... keine ahnung warum...

un deshalb können wir halt auch nich die funktionalität unserer funktionen testen...
deshalb bitten wir hier mal wieder um hilfe :O

PHP:
# include<stdio.h>
# include<string.h>



typedef struct
{
	int id, vid, mid;
	char name[25], geschlecht;
}
FAMILIENMITGLIED;



struct listelement
{
	FAMILIENMITGLIED *mitglied;
	struct listelement *rechts;
};



struct listelement* file_lesen (char *filename)
{
	FILE *fp;
	struct listelement *first = NULL, *zwischen = NULL, *einlist = NULL;
	FAMILIENMITGLIED *mitglied;
	char geschl0, name0[25];
	int id0, vid0, mid0;
	fp = fopen(filename, "r");
	while (!feof (fp))
	{
	 fscanf(fp, "%d %s %c %d %d\n", &id0, name0, &geschl0, &vid0, &mid0);
	 mitglied = malloc(sizeof(FAMILIENMITGLIED));
	 mitglied->id = id0;
	 strcpy (mitglied->name, name0);
	 mitglied->geschlecht = geschl0;
	 mitglied->vid = vid0;
	 mitglied->mid = mid0;
	 einlist=malloc(sizeof(struct listelement));	
 	 einlist->mitglied = mitglied;
 	 if (!first) first = einlist;
 	 if (zwischen) zwischen->rechts = einlist;
 	 zwischen = einlist;
 	}
	fclose (fp);	
 	return first;	
}



void file_schreiben (struct listelement *list, char *filename)
{
	FILE *fp;
	struct listelement *first = NULL, *zwischen = NULL, *einlist = NULL;
	FAMILIENMITGLIED *mitglied;
	char geschl0, name0[25];
	int id0, vid0, mid0;
	fp = fopen(filename, "w");
	while (list)
	{
	 fprintf (fp, "%d %s %c %d %d\n",  list->mitglied->id, list->mitglied->name, list->mitglied->geschlecht, list->mitglied->vid, list->mitglied->mid);
	 list = list->rechts;
	}
	fclose (fp);		
}



int id_kleinstesuchen (struct listelement *start)
{
	int id1, id2, id;
	while (start != 0)
	{
	 id1 = start->mitglied->id;
	 id2 = start->rechts->mitglied->id;
	 if (id1 < id2)
	 {
	  id = start->rechts->mitglied->id;
	  start = start->rechts;
	 }
	 else 
	 {
	  id = start->mitglied->id;
	  start = start->rechts;
	 }
	}
	return id;
}



struct listelement *insert_right(struct listelement *list, FAMILIENMITGLIED *mitglied, char *filename)
{
	FILE *fp;
	struct listelement *new;
	new = malloc(sizeof(struct listelement));
	new->mitglied = mitglied;
	new->mitglied->id = id_kleinstesuchen(list);
	new->rechts = list->rechts;
	list->rechts = new;
	fp = fopen(filename, "w+");
	fseek (fp, 0, SEEK_END);
	fprintf(fp,"%d %s %c %d %d\n", new->mitglied->id, new->mitglied->name, new->mitglied->geschlecht, new->mitglied->vid, new->mitglied->mid);
	fclose (fp);
	return new;
}



struct listelement *delete(struct listelement *list, char name[25], char *filename)
{
	struct listelement *tmp;
	tmp = malloc (sizeof(struct listelement));
	while(list != 0)
	{
	 if (strcmp(list->mitglied->name,name) == 0)
	 {
	  tmp->rechts = tmp->rechts->rechts;
	  list = tmp;
	  free(tmp);
	  file_schreiben(list, filename);
	  return list;
	 }
	 tmp = list;
	 list = list->rechts;
	}
}



void print_all(struct listelement* list)
{
	struct listelement *gen1 = NULL, *zwischen1 = NULL, *einlist1 = NULL, *gen2 = NULL, *zwischen2 = NULL, *einlist2 = NULL, *gen3 = NULL, *zwischen3 = NULL, *einlist3 = NULL;
	struct listelement *eins = list, *zwei = list, *drei =list;
	while (list)
	{
	 if (list->mitglied->vid == -1 && list->mitglied->mid == -1)
	 {
	  printf("%s\t", list->mitglied->name);
	  einlist1 = malloc(sizeof(struct listelement));	
 	  einlist1->mitglied = list->mitglied;
 	  if (!gen1) gen1 = einlist1;
 	  if (zwischen1) zwischen1->rechts = einlist1;
 	  zwischen1 = einlist1;
 	 }
	 list=list->rechts;
	}
	printf("\n");
	while (eins)
	{
	 while(gen1)
	 {
	  if (eins->mitglied->vid == gen1->mitglied->id)
	  {
	   printf("%s\t", eins->mitglied->name);
	   einlist2 = malloc(sizeof(struct listelement));	
 	   einlist2->mitglied = eins->mitglied;
 	   if (!gen2) gen2 = einlist2;
 	   if (zwischen2) zwischen2->rechts = einlist2;
 	   zwischen2 = einlist2;
 	  }
	  gen1 = gen1->rechts;
	 }
	 eins=eins->rechts;
	}
	printf("\n");
	free(einlist1);
	while (zwei)
	{
	 while(gen2)
	 {
	  if (zwei->mitglied->vid == gen2->mitglied->id)
	  {
	   printf("%s\t", zwei->mitglied->name);
	   einlist3 = malloc(sizeof(struct listelement));	
 	   einlist3->mitglied = eins->mitglied;
 	   if (!gen3) gen3 = einlist3;
 	   if (zwischen3) zwischen3->rechts = einlist3;
 	   zwischen3 = einlist3;
 	  }
	  gen2 = gen2->rechts;
	 }
	 zwei=zwei->rechts;
	}
	printf("\n");
	free(einlist2);
	while (drei)
	{
	 while(gen3)
	 {
	  if (drei->mitglied->vid == gen3->mitglied->id) printf("%s\t", drei->mitglied->name);
	  gen3 = gen3->rechts;
	 }
	 drei=drei->rechts;
	}
	printf("\n");
	free(einlist3);
}



struct listelement *change (struct listelement *list, FAMILIENMITGLIED *mitglied, char *filename)
{
	FAMILIENMITGLIED *mitglied1;
	char geschl0, name0[25];
	int id0, vid0, mid0;
	while(list != 0)
	{
	 if (list->mitglied->id == mitglied->id)
	 {
	  printf("gebe alle Daten zu der Person an.");
	  scanf("%d %s %c %d %d\n", &id0, name0, &geschl0, &vid0, &mid0);
	  mitglied1 = malloc(sizeof(FAMILIENMITGLIED));
	  mitglied1->id = id0;
	  strcpy (mitglied1->name, name0);
	  mitglied1->geschlecht = geschl0;
	  mitglied1->vid = vid0;
	  mitglied1->mid = mid0;
	  list->mitglied = mitglied1;
	  list = list->rechts;
	 }
	}
	file_schreiben (list, filename);
	return list;
}



FAMILIENMITGLIED* personsuchen (struct listelement *list, char *name)
{
	struct listelement *head = list;
	FAMILIENMITGLIED *mitglied;
	while(head != 0)
	{
	 if (strcmp(head->mitglied->name,name) == 0)
	 {
	  strcpy (mitglied->name, name);
	  mitglied->geschlecht = head->mitglied->geschlecht;
	  mitglied->id = head->mitglied->id;
	  mitglied->vid = head->mitglied->vid;
	  mitglied->mid = head->mitglied->mid;
	 }
	 head = head->rechts;
	}
	return mitglied;
}



int mamapapasohntochter (struct listelement *list, char name1[25], char name2[25])
{
	FAMILIENMITGLIED *mitglied1, *mitglied2;
	mitglied1 = personsuchen(list, name1);
	mitglied2 = personsuchen(list, name2);
	if (mitglied1->vid == mitglied2->id)
	{
	 printf("%s ist der Papa von %s", mitglied2->name, mitglied1->name);
	 return 0;
	}
	if (mitglied2->vid == mitglied1->id)
	{
	 printf("%s ist der Papa von %s", mitglied1->name, mitglied2->name);
	 return 0;
	}
	if (mitglied1->mid == mitglied2->id)
	{
	 printf("%s ist die Mama von %s", mitglied2->name, mitglied1->name);
	 return 0;
	}
	if (mitglied2->mid == mitglied1->id)
	{
	 printf("%s ist die Mama von %s", mitglied1->name, mitglied2->name);
	 return 0;
	}
	return 1;
}



int onkeltantenichteneffe (struct listelement *list, char name1[25], char name2[25]) 
{
	char geschl = 'M';
	struct listelement *eins = list, *zwei =list;
	FAMILIENMITGLIED *mitglied1, *mitglied2, *elter;
	mitglied1 = personsuchen(list, name1);
	mitglied2 = personsuchen(list, name2);
	while(eins != 0)
	{
	 if (eins->mitglied->id == mitglied1->vid || eins->mitglied->id == mitglied1->mid)
	 { 
	  elter = personsuchen(list, eins->mitglied->name);
	  if (eins->mitglied->vid == mitglied2->vid)
	  {
	   if (mitglied2->geschlecht == geschl)
	   {printf("%s ist der Onkel von %s", mitglied2->name, mitglied1->name); return 0;}
	   else {printf("%s ist die Tante von %s", mitglied2->name, mitglied1->name); return 0;}
	  }
	 }
	 eins = eins->rechts;
	}
	while(zwei != 0)
	{
	 if (zwei->mitglied->id == mitglied2->vid || zwei->mitglied->id == mitglied2->mid)
	 { 
	  elter = personsuchen(list, zwei->mitglied->name);
	  if (zwei->mitglied->vid == mitglied1->vid)
	  {
	   if (mitglied1->geschlecht == geschl)
	   {printf("%s ist der Onkel von %s", mitglied1->name, mitglied2->name); return 0;}
	   else {printf("%s ist die Tante von %s", mitglied1->name, mitglied2->name); return 0;}
	  }
	 }
	 zwei = zwei->rechts;
	}
	return 1;
}



int omiopienkel (struct listelement *list, char name1[25], char name2[25])
{
	struct listelement *list2 = list;
	FAMILIENMITGLIED *mitglied1, *mitglied2, *elter;
	mitglied1 = personsuchen(list, name1);
	mitglied2 = personsuchen(list, name2);
	while (list != 0)
	{
	 if (list->mitglied->id == mitglied1->vid || list->mitglied->id == mitglied1->vid)
	 {
	  elter = personsuchen(list, list->mitglied->name);
	  if (elter->vid == mitglied2->id)
	  {printf("%s ist der Opa von %s", mitglied2->name, mitglied1->name); return 0;}
	  if (elter->mid == mitglied2->id)
	  {printf("%s ist die Oma von %s", mitglied2->name, mitglied1->name); return 0;}
	 }
	 list = list->rechts;
	}
	while (list2 != 0)
	{
	 if (list2->mitglied->id == mitglied2->vid || list2->mitglied->id == mitglied2->vid)
	 {
	  elter = personsuchen(list2, list2->mitglied->name);
	  if (elter->vid == mitglied1->id)
	  {printf("%s ist der Opa von %s", mitglied1->name, mitglied2->name); return 0;}
	  if (elter->mid == mitglied1->id)
	  {printf("%s ist die Oma von %s", mitglied1->name, mitglied2->name); return 0;}
	 }
	 list2 = list2->rechts;
	}
	return 1;
}



int cousin (struct listelement *list, char name1[25], char name2[25])
{
	struct listelement *liste2 = list;
	struct listelement *liste3 = list;
	struct listelement *liste4 = list;
	FAMILIENMITGLIED *mitglied1, *mitglied2, *elter;
	mitglied1 = personsuchen(list, name1);
	mitglied2 = personsuchen(list, name2);
	while (list != 0)
	{
	 if(list->mitglied->id == mitglied1->vid)
	 {
	  elter = personsuchen(list, list->mitglied->name);
	  while (liste2 != 0)
	  {
	   if(liste2->mitglied->id == mitglied2->vid || liste2->mitglied->id == mitglied2->mid)
	   {
	    if (elter->vid == liste2->mitglied->vid) printf ("%s ist Cousin(e) von %s", mitglied1, mitglied2);
	    return 0;
	   }
	   liste2 = liste2->rechts;
	  }
	 }
	list = list->rechts;
	}
	while (liste3 != 0)
	{
	 if(liste3->mitglied->id == mitglied1->mid)
	 {
	  elter = personsuchen(liste3, liste3->mitglied->name);
	  while (liste4 != 0)
	  {
	   if(liste4->mitglied->id == mitglied2->vid || liste4->mitglied->id == mitglied2->mid)
	   {
	    if (elter->vid == liste4->mitglied->vid) printf ("%s ist Cousin(e) von %s", mitglied1, mitglied2);
	    return 0;
	   }
	   liste4 = liste4->rechts;
	  }
	 }
	liste3 = liste3->rechts;
	}
	return 1;
}



int schwaEgerIN (struct listelement *list, char name1[25], char name2[25])
{
	char geschl = 'M';
	struct listelement *list2 = list, *list3 = list, *list4 = list;
	FAMILIENMITGLIED *mitglied1, *mitglied2, *elter;
	mitglied1 = personsuchen(list, name1);
	mitglied2 = personsuchen(list, name2);
	if (mitglied1->geschlecht == geschl)
	while (list != 0)
	{
	 if (list->mitglied->vid == mitglied1->id)
	 while (list2 != 0)
	 {
	  if (list2->mitglied->id == list->mitglied->mid)
	  if (list2->mitglied->mid == mitglied2->mid)
	  {printf("%s ist der Schwager von %s\n", mitglied1, mitglied2); return 0;}
	  list2 = list2->rechts;
	 }
	 list = list->rechts;
	}
	else
	while (list != 0)
	{
	 if (list->mitglied->mid == mitglied1->id)
	 while (list2 != 0)
	 {
	  if (list2->mitglied->id == list->mitglied->vid)
	  if (list2->mitglied->mid == mitglied2->mid)
	  {printf("%s ist die Schwaegerin von %s\n", mitglied1, mitglied2); return 0;}
	  list2 = list2->rechts;
	 }
	 list = list->rechts;
	}
	if (mitglied2->geschlecht == geschl)
	while (list3 != 0)
	{
	 if (list3->mitglied->vid == mitglied2->id)
	 while (list4 != 0)
	 {
	  if (list4->mitglied->id == list3->mitglied->mid)
	  if (list4->mitglied->mid == mitglied1->mid)
	  {printf("%s ist der Schwager von %s\n", mitglied2, mitglied1); return 0;}
	  list4 = list4->rechts;
	 }
	 list3 = list3->rechts;
	}
	else
	while (list3 != 0)
	{
	 if (list3->mitglied->mid == mitglied2->id)
	 while (list4 != 0)
	 {
	  if (list3->mitglied->id == list3->mitglied->vid)
	  if (list3->mitglied->mid == mitglied1->mid)
	  {printf("%s ist die Schwaegerin von %s\n", mitglied2, mitglied1); return 0;}
	  list4 = list4->rechts;
	 }
	 list3 = list3->rechts;
	}
	return 1;
}



int schwiegereltern (struct listelement *list, char name1[25], char name2[25])
{
	char geschl = 'M';
	struct listelement *list2 = list, *list3 = list, *list4 = list;
	FAMILIENMITGLIED *mitglied1, *mitglied2, *elter;
	mitglied1 = personsuchen(list, name1);
	mitglied2 = personsuchen(list, name2);
	if (mitglied1->geschlecht == geschl)
	while (list != 0)
	{
	 if (list->mitglied->vid == mitglied1->id)
	 while (list2 != 0)
	 {
	  if (list2->mitglied->id == list->mitglied->mid)
	  if (list2->mitglied->mid == mitglied2->id || list2->mitglied->vid == mitglied2->id)
	  {printf("%s ist der Schwiegersohn von %s\n", mitglied1, mitglied2); return 0;}
	  list2 = list2->rechts;
	 }
	 list = list->rechts;
	}
	else
	while (list != 0)
	{
	 if (list->mitglied->mid == mitglied1->id)
	 while (list2 != 0)
	 {
	  if (list2->mitglied->id == list->mitglied->vid)
	  if (list2->mitglied->mid == mitglied2->id || list2->mitglied->vid == mitglied2->id)
	  {printf("%s ist die Schwiegertochter von %s\n", mitglied1, mitglied2); return 0;}
	  list2 = list2->rechts;
	 }
	 list = list->rechts;
	}
	if (mitglied2->geschlecht == geschl)
	while (list3 != 0)
	{
	 if (list3->mitglied->vid == mitglied2->id)
	 while (list4 != 0)
	 {
	  if (list4->mitglied->id == list3->mitglied->mid)
	  if (list4->mitglied->mid == mitglied1->id || list4->mitglied->vid == mitglied1->id)
	  {printf("%s ist der Schwiegersohn von %s\n", mitglied2, mitglied1); return 0;}
	  list4 = list4->rechts;
	 }
	 list3 = list3->rechts;
	}
	else
	while (list3 != 0)
	{
	 if (list3->mitglied->mid == mitglied2->id)
	 while (list4 != 0)
	 {
	  if (list4->mitglied->id == list3->mitglied->vid)
	  if (list4->mitglied->mid == mitglied1->id || list4->mitglied->vid == mitglied1->id)
	  {printf("%s ist die Schwiegertochter von %s\n", mitglied2, mitglied1); return 0;}
	  list4 = list4->rechts;
	 }
	 list3 = list3->rechts;
	}
	return 1;
}



int main (int argc, char **argv)
{
	FAMILIENMITGLIED *mitglied;
	char *filename = "Family";
	struct listelement *start, *list;
	start = file_lesen(filename);
	list = start;

	if (argv[1] == "-" && argv[2] == "a")
	{
	 mitglied = personsuchen (list, argv[3]);
	 insert_right (start, mitglied, filename);
	 return 0;
	}
	if (argv[1] == "-" && argv[2] == "d")
	{delete(start, argv[3], filename); return 0;}
	if (argv[1] == "-" && argv[2] == "c")
	{
	 mitglied = personsuchen (list, argv[3]);
	 change (start, mitglied, filename);
	}
	if (argv[1] == "-" && argv[2] == "p")
	{print_all (start); return 0;}
	if (argv[1] == "-" && argv[2] == "v")
	{
	 mamapapasohntochter (start, argv[3], argv[4]);
	 if (mamapapasohntochter (start, argv[3], argv[4]) == 0) return 0;
	 else onkeltantenichteneffe (start, argv[3], argv[4]);
	 if (onkeltantenichteneffe (start, argv[3], argv[4]) == 0) return 0;
	 else omiopienkel (start, argv[3], argv[4]);
	 if (omiopienkel (start, argv[3], argv[4]) == 0) return 0;
	 else cousin (start, argv[3], argv[4]);
	 if (cousin (start, argv[3], argv[4]) == 0) return 0;
	 else schwaEgerIN (start, argv[3], argv[4]);
	 if (schwaEgerIN (start, argv[3], argv[4]) == 0) return 0;
	 else schwiegereltern (start, argv[3], argv[4]);
	 if (schwiegereltern (start, argv[3], argv[4]) == 1) printf("nicht verwandt\n");
	}
	printf(" hinzufuegen: -a 'name',\n loeschen: -d 'name',\n veraendern: -c 'name',\n ausgeben: -p,\n verwandschaftliche beziehung: -v 'name' 'name'\n");
	return 0;
}

wird irgwann mal noch in verschiedene header-datein geschrieben...

kann jemand weiter helfen??
und: sorry... aba wir sin echt so unbegabt...:rolleyes:

ciao
 
Mit argv[1] == "-" wird die Adresse, auf die argv[1] zeigt mit der Adresse verglichen, in der sich der String "-" befindet. Dieser Vergleich schlaegt in aller Regel fehl. Strings werden in C u.a. mit der Funktion strcmp() verglichen, bei Gleichheit ist der Funktionswert 0. Der Vergleich sollte also if (strcmp(argv[1], "-") == 0) lauten.
Da aber die Optionen beispielsweise "-p" geprueft werden sollen, muss man das Ganze etwas anderst formulieren: Die Liste argv[] enthält Zeiger auf alle dem Programm mitgegebenen Parameter, wobei argv[0] der Name des Programms ist. Wird das Programm beispielsweise mit Stammbaum -p -a aufgerufen enthaelt argv[0] den Zeiger auf den Text Stammbaum, argv[1] den Zeiger auf den Text -p und argv[2] den Zeiger auf den Text -a. Im Programm koennte die Pruefung also wie folgt aussehen:

Code:
int main(int argc, char *argv[])
{
  int i;

  for (i =1; i < argc; i++)
  {
    if (strcmp(argv[i], "-p") == 0)
    {
      printf("Option '-p' gefunden\n");
    }
    else  if (strcmp(argv[i], "-a") == 0) 
    {
      printf("Option '-p' gefunden\n");
    }
  }
}
 
Zurück
Oben