Informatiker Board (http://www.informatikerboard.de/board/index.php)
- Themengebiete (http://www.informatikerboard.de/board/board.php?boardid=1)
--- Praktische Informatik (http://www.informatikerboard.de/board/board.php?boardid=6)
---- Softwaretechnik (http://www.informatikerboard.de/board/board.php?boardid=18)
----- einfach verkettete Listen in C -Programmhilfe (http://www.informatikerboard.de/board/thread.php?threadid=2802)


Geschrieben von Lars am 23.01.2016 um 17:33:

  einfach verkettete Listen in C -Programmhilfe

So, ich hab mich hier jetzt auch mal registriert! Wink
Aber nun zum eig. Thema. Die Aufgabe wie immer im Anhang. Bitte erstmal keine Komplettlösung, ich häng gerade nur an einer Stelle.
Bin gerade beim 2. Stichpunkt.
Mein Code sieht zurzeit so aus:
code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
#include <stdio.h>
#include <stdlib.h>
#include "readline.h"
#include <time.h>
typedef struct person{
	char nameperson[20];
	char Abteilung;
	int TelNr;
}Person;

int neuePerson()
{
	Person* p=(Person*)malloc(sizeof(Person));
	readLine(p->nameperson, 20);
	srand (time(NULL));
	p->TelNr=rand()%100;
	p->Abteilung = rand() % 3 + 65; 
	printf("%s, %c, %i\n",p->nameperson,p->Abteilung,p->TelNr); //zur Überprüfung, ob das ganze bis jetzt funktioniert
};

int main()
{
	printf("Bitte im Folgenden 10 Mitarbeiternamen (jeweils mit Enter) eingeben...\n");
	for(int i=0; i<10; i++)neuePerson();
}


Das Programm funktioniert bis dahin (ist ja auch nicht viel), aber da ich 10 Namen speichern muss, weiß ich gerade nicht wie ich realisieren kann, dass beim Neuausführen der Schleife nicht die alten Werte überschrieben werden. Ich brauch ja theoretisch immer nen anderen Pointer den ich zurückgeben muss, auf das jeweilige struct mit den gespeicherten Daten oder?
Hilfe wäre ganz lieb smile .



Geschrieben von eulerscheZahl am 23.01.2016 um 17:39:

 

Dann willkommen an Bo(a)rd.
Bei einer verketteten Liste braucht die Person noch einen Zeiger auf die nächste Person.
Und dann folgst du so lange den Zeigern, bis du am Ende bist, um dort eine Person anzuhängen.
Und wenn du nichts zurückgeben willst, deklarier die Funktion als void.



Geschrieben von Lars am 23.01.2016 um 17:46:

 

Ok, ich versuch mich mal und schau mal, ob was bei rumkommt. Ansonsten meld ich mich hier wieder.
Funktion ist jetzt als void deklariert Daumen hoch



Geschrieben von Lars am 23.01.2016 um 19:07:

 

code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
#include <stdio.h>
#include <stdlib.h>
#include "readline.h"
#include <time.h>
typedef struct person{
	char nameperson[20];
	char Abteilung;
	int TelNr;
	struct person *next;
	struct person *anfang;
}Person;
struct person *next = NULL;
struct person *anfang = NULL;

int neuePerson()
{	
struct person* zeiger;
if(anfang==NULL){  
	anfang=(Person*)malloc(sizeof(struct person));
	readLine(anfang->nameperson, 20);
	srand (time(NULL));
	anfang->TelNr=rand()%100;
	anfang->Abteilung = rand() % 3 + 65; 
	anfang->next=NULL;
	}
else{
	zeiger=anfang;
	while(zeiger->next != NULL) zeiger=zeiger->next;
	if(zeiger->next == NULL){
		zeiger->next=(Person*)malloc(sizeof(struct person));
		zeiger=zeiger->next;
		readLine(zeiger->nameperson, 20);
		srand (time(NULL));
		zeiger->TelNr=rand()%100;
		zeiger->Abteilung = rand() % 3 + 65; 
		zeiger->next=NULL;
	}
}
}


void neuesListenElement()
{
	
}

void listeAusgeben()
{
	
}

int main()
{
	printf("Bitte im Folgenden 10 Mitarbeiternamen (jeweils mit Enter) eingeben...\n");
	for(int i=0; i<10; i++)neuePerson();
}

Ist das so richtig, ich glaube nicht x).



Geschrieben von Lars am 23.01.2016 um 19:19:

 

Die uns gegebene readLine Funktion sieht so aus:
code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
/* Diese Datei muss einfach nur im selben Verzeichnis liegen wie die Datei, die 
   readLine benutzt. Dort muss dann die Funktion mit 
   #include "readline.h"
   eingebunden werden. Am Compileraufruf aendert sich nichts. */
/* Nutzung der Funktion: 
   strbuffer muss ein Pointer auf einen genuegend grossen char-Array sein
   buffersize muss die Groesse dieses char-Arrays angeben.
   Bei Aufruf von readLine wird dann vom Terminal eine Zeichenkette (inklusive Leerzeichen)
   eingelesen, bis der Nutzer Enter drueckt oder bis die maximale Arraylaenge erreicht ist.
   Das "Enter" wird nicht in den String mitgespeichert. */
  
#ifndef READLINE_H
#define READLINE_H

#include <stdio.h>

void readLine( char* strbuffer, unsigned int buffersize )
{
  char format[30] = "";
  sprintf( format, "%%%u[^\n]%%*c", buffersize-1 );
  scanf( format, strbuffer );
}

#endif //#ifndef READLINE_H



Geschrieben von Lars am 23.01.2016 um 19:55:

 

code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
#include <stdio.h>
#include <stdlib.h>
#include "readline.h"
#include <time.h>
typedef struct person{
	char nameperson[20];
	char Abteilung;
	int TelNr;
	struct person *next;
	struct person *anfang;
}Person;
struct person *next = NULL;
struct person *anfang = NULL;

int neuePerson(void)
{	
struct person* zeiger;
if(anfang==NULL){  
	anfang=(Person*)malloc(sizeof(struct person));
	readLine(anfang->nameperson, 20);
	srand (time(NULL));
	anfang->TelNr=rand()%100;
	anfang->Abteilung = rand() % 3 + 65; 
	anfang->next=NULL;
	}
else{
	zeiger=anfang;
	while(zeiger->next != NULL) zeiger=zeiger->next;
	if(zeiger->next == NULL){
		zeiger->next=(Person*)malloc(sizeof(struct person));
		zeiger=zeiger->next;
		readLine(zeiger->nameperson, 20);
		srand (time(NULL));
		zeiger->TelNr=rand()%100;
		zeiger->Abteilung = rand() % 3 + 65; 
		zeiger->next=NULL;
	}
}
}


void neuesListenElement()
{
	
}

void listeAusgeben(void)
{
	struct person* zeiger = anfang;
	printf("Personalpool Firma:\n");
	while(zeiger != NULL){
		printf("name: %s	abteilung: %i	telNr: %i\n",zeiger->nameperson, zeiger->Abteilung, zeiger->TelNr);
		zeiger=zeiger->next;
	}
	printf("Personalpool ferig -- Anzahl Mitarbeiter: 10\n");
	
}

int main()
{
	printf("Bitte im Folgenden 10 Mitarbeiternamen (jeweils mit Enter) eingeben...\n");
	for(int i=0; i<10; i++)neuePerson();
	listeAusgeben();
	
}

Sooo, das sieht doch schonmal gut aus. Fehlt noch das Sortieren, kann sein, dass du mir da nen bisschen helfen musst. Aber ich versuche mich erst smile .



Geschrieben von Lars am 23.01.2016 um 20:27:

 

Ok, ich require dann doch nochmal help hier. Ich bekomm das nicht hin, dass ich die Elemente der Liste jetzt in eine andere Liste nochmal ordne. Mir fehlt irgendwie der Ansatz...
Mann, ich war sooo naaah dran traurig .
Edit: Nächstes mal nutz ich die Edit-Funktion, sorry Augenzwinkern .



Geschrieben von eulerscheZahl am 23.01.2016 um 20:28:

 

Dann spoiler ich mal nicht zu viel: ich würde es mit Bubblesort machen.
Edit: dank Karlito habe ich ein Script, das mich über neue Beiträge informiert. Edits werden da aber nicht erkannt. Insofern ist ein neuer Beitrag schon ok.



Geschrieben von Lars am 23.01.2016 um 20:39:

 

Ok! Dann dann kann ich ja munter weiterposten smile . Ich kannte Bubblesort bis jetzt noch gar nicht, hab mich gerade mal informiert. Ist eine geniale Funktion, bringt mir leider in dem Falle nichts. Hab mal eine Datei mit der Beispielausgabe, die uns gegeben wurde, hochgeladen. Da soll ja eine zweite Liste nochmal ausgegeben werden, wo dann jeweils einmal der Pool ist und dann eben die sortierte Liste, während der Pool eben immer kleiner wird und die Liste dann die nach den Abteilungen geordneten Personen aufweist.



Geschrieben von eulerscheZahl am 23.01.2016 um 20:48:

 

Im Allgemeinen gibt es besseres, geht nur meines Wissens nicht mit verketteten Listen.
Erstelle dir eine zweite Liste und füge dann per InsertionSort dorthin ein.



Geschrieben von Lars am 23.01.2016 um 21:03:

 

Ok, ich probiere mich!



Geschrieben von Lars am 24.01.2016 um 11:54:

 

Ok, übrigens sollen wir keine Algorithmen nutzen, jemand hat im Forum nachgefragt:
Mein jetziger Code:
code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
#include <stdio.h>
#include <stdlib.h>
#include "readline.h"
#include <time.h>
typedef struct person{
	char nameperson[20];
	char Abteilung;
	int TelNr;
	struct person *next;
	struct person *anfang;
}Person;
struct person *next = NULL;
struct person *anfang = NULL;

typedef struct sortiert{
	char nameperson[20];
	char Abteilung;
	int TelNr;
	struct sortiert *next;
	struct sortiert *anfang;
}Sortiert;
struct sortiert *snext = NULL;
struct sortiert *sanfang = NULL;


int neuePerson(void)
{	
struct person* zeiger;
if(anfang==NULL){  
	anfang=(Person*)malloc(sizeof(struct person));
	readLine(anfang->nameperson, 20);
	srand (time(NULL));
	anfang->TelNr=rand()%100;
	anfang->Abteilung = rand() % 3 + 65; 
	anfang->next=NULL;
	}
else{
	zeiger=anfang;
	while(zeiger->next != NULL) zeiger=zeiger->next;
	if(zeiger->next == NULL){
		zeiger->next=(Person*)malloc(sizeof(struct person));
		zeiger=zeiger->next;
		readLine(zeiger->nameperson, 20);
		srand (time(NULL));
		zeiger->TelNr=rand()%100;
		zeiger->Abteilung = rand() % 3 + 65; 
		zeiger->next=NULL;
	}
}
}


void neuesListenElement()
{
	struct person* zeiger;
	struct person* zeiger1;
	struct sortiert* zeiger2;
	printf("=== sortieren... ===\nnoch im allgemeinen Pool: \n");
	if(sanfang==NULL){
		sanfang=(Sortiert*)malloc(sizeof(struct sortiert));
		if(anfang!=NULL){
			if((anfang->Abteilung)=='A'){
			sanfang->Abteilung=anfang->Abteilung; sanfang->TelNr=anfang->TelNr; free(anfang); anfang=zeiger;}
			else{
				zeiger=anfang;
				while(zeiger->next!=NULL){
					zeiger1=zeiger->next;
					if(zeiger1->Abteilung=='A'){
						sanfang->Abteilung=zeiger1->Abteilung;
						sanfang->TelNr=zeiger1->TelNr;
						zeiger->next=zeiger1->next;
						free(zeiger1);
						break;
					}
					zeiger=zeiger1;
				}
			}
			
		
		}
	}
	else{
		zeiger2=sanfang;
		while(zeiger2->next!=NULL){zeiger2=zeiger2->next;
		if(zeiger2->next==NULL){
			zeiger2->next=(Sortiert*)malloc(sizeof(struct sortiert));
			zeiger2=zeiger2->next;
			
			zeiger2->next=NULL;
		}
		}
		
	}
	printf("\n \n [...] \n \n ");
	
}


void listeAusgeben(void)
{
	struct person* zeiger = anfang;
	printf("Personalpool Firma:\n");
	while(zeiger != NULL){
		printf("name: %s	abteilung: %c	telNr: %i\n",zeiger->nameperson, zeiger->Abteilung, zeiger->TelNr);
		zeiger=zeiger->next;
	}
	printf("Personalpool ferig -- Anzahl Mitarbeiter: 10\n");
	
}

void listeAusgeben2(void)
{
	struct sortiert* zeiger3 = sanfang;
	printf("sortiert:\n");
	while(zeiger3!=NULL){
		printf("name: %s	abteilung: %c	telNr: %i\n",zeiger3->nameperson, zeiger3->Abteilung, zeiger3->TelNr),
		zeiger3=zeiger3->next;
	}
}

int main()
{
	printf("Bitte im Folgenden 10 Mitarbeiternamen (jeweils mit Enter) eingeben...\n");
	for(int i=0; i<10; i++)neuePerson();
	listeAusgeben();
	for(int s=0; s<10; s++){
	neuesListenElement();listeAusgeben();listeAusgeben2();}
	
	
}

Sooo, Prinzipiell durchsucht wird jetzt die Liste nach einem 'A', dann werden die Werte in das erste Element der 2. Liste übernommen und der Speicher der ersten Liste freigegeben. Nun muss ich das noch vervollständigen, dass es, falls der zweite Listenanfang nicht mehr auf NULL zeigt auch nochmal nach den A's sucht und dann, wenn kein A mehr existiert jeweils nach den B's und C's. Bloß ist das so umständlich, dass ich schon wieder am Rad drehe. Ich steig langsam nicht mehr durch, wer hat sich denn bitte diese Aufgabe ausgedacht böse . Ok, außerdem kann ich sanfang->nameperson=anfang->nameperson nicht machen, dann spuckt er mir aus "invalid array assignment, wahrscheinlich weil ich nicht einfach so das array gleichsetzen kann. Wie kann man das einfach umschreiben? Mir fällt grad nichts mehr ein, seit gestern häng ich an dieser Aufgabe, Konzentration schwächelt imo. smile



Geschrieben von eulerscheZahl am 24.01.2016 um 12:57:

 

Du brauchst keine eigene struct für die sortierten Einträge, das sind weiterhin Personen.
Du musst beim Sortieren noch nicht mal neue Personen erstellen, du kannst sie aus der alten Liste entfernen und in die neue einbauen.
Du musst beim Einfügen 6 Fälle unterscheiden:
1. die sortierte Liste ist leer.
2. Du bist bei der Suche, wo du einfügen willst vor dem ersten Listeneintrag
2.1 Der neue Eintrag muss ganz an den Anfang
2.2 Der neue Eintrag gehört dahinter
3. Du bist irgendwo in der Mitte der Liste
3.1 Der neue Eintrag gehört da rein, wo du gerade bist
3.2 Du musst weiter nach hinten laufen
4. Du bist bereits hinter dem letzten Eintrag

Du musst 2 Knoten kennen: den vor und nach der aktuellen Position (nur so kannst du einfügen, ohne die Listenstruktur kaputtzumachen).

Ein if((anfang->Abteilung)=='A') brauchst du nicht, prüfe einfach if (zeiger1->Abteilung > zeiger2->Abteilung), wenn du wissen willst, wer von beiden größer ist.

Und das sturktuierte Vorgehen nach einem festen Schema ist die Definition eines Algorithmus. Ohne dessen Verwendung lässt sich die Aufgabe nicht lösen.



Geschrieben von Lars am 24.01.2016 um 17:47:

  RE: einfach verkettete Listen in C -Programmhilfe

So, bin gerade wiedergekommen, noch 6h an Zeit das zu Ende zu schreiben, Zeit für den Endspurt.
Ich versteh irgendwie deine ersten 3 Zeile nicht.
Ich brauche also das gesamte struct sortieren nicht? Und ich soll keine neuen personen erstellen sondern einfach die, die ich entferne in die neue Liste übertragen?
Das klingt irgendwie gerade zu abstrakt für mich verwirrt .
Wir hatten Listen erst letzte Woche und das ist bis jetzt das verwirrendste Thema, ich musste mir auch ne Skizze für das Prog. malen, weil ich sonst nicht durchgestiegen bin Zunge raus .



Geschrieben von eulerscheZahl am 24.01.2016 um 17:50:

 

code:
1:
2:
3:
4:
5:
6:
7:
typedef struct sortiert{
	char nameperson[20];
	char Abteilung;
	int TelNr;
	struct sortiert *next;
	struct sortiert *anfang;
}Sortiert;

Das ist kein Unterschied zu Person. also brauchst du diese struct auch nicht. Alles was du damit machen kannst, geht auch mit Person.
Du hast zwei Listen. Nacheinander nimmst du die Personen aus der einen Liste raus und tust sie direkt in die andere rein. Dafür brauchst du kein malloc.

Ach ja: das mal sich bei den Zeigern Skizzen macht um nicht durcheinander zu kommen, ist ganz normal. Mache ich auch manchmal noch.


Forensoftware: Burning Board, entwickelt von WoltLab GmbH