PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Bäume und Listen



christophwth
27-09-2000, 18:14
Hallo

mein Posting hat nichts mit Linux zu tun, aber Ich stehe vor dem Problem
Das ich mit Binärbäumen und verketten Listen arbeiten muß. ?
Ich habe mit typedef folgende structs bekannt gegeben.
Für die Liste :

typedef struct liste {
int wert ;
struct liste *next;
} LISTE;

Für den Baum :

typedef struct knoten{
struct LISTE *pl;
struct knoten *pr;
struct knoten *pl;
}KNOTEN;
Es gibt eine Funktion die mir einen Binärbaum erzeugt.In den Knoten sollen
Zeiger auf die Listenelemente gespeichert werden.

Jetzt will ich innerhalb der Baum-Funktion auf die Komponente wert der LISTE zugreifen.

wie mach ich das ??

mein Versuch sieht so aus printf("%i",pnode.pl.wert);
(pnode vom Typ KNOTEN )

Wo ist mein Denkfehler ?

gcc Fehlermeldung: request for member 'zl' in something not a structure or
union

Danke schon im Voraus

Gruss
Christoph


thommy
28-09-2000, 07:53
Sind paar kleine Schreibfehler drin:

<pre>
#include &lt;stdio.h&gt;


typedef struct liste {
int wert ;
struct liste *next;
} LISTE;

typedef struct knoten{
LISTE *zl;
struct knoten *pr;
struct knoten *pl;
}KNOTEN;

int main() {
KNOTEN pnode;
pnode.zl = (struct liste*) malloc (sizeof(struct liste));
pnode.zl-&gt;wert = 10;
printf("%i", pnode.zl-&gt;wert);
return 0;
}
</pre>

Thomas

Christoph
28-09-2000, 08:13
Ein Tip, wie du dir viel Arbeit ersparen kannst:
verwende C++ und die STL (standard Template Library).
Da gibt es die benötigten Datenstrukturen schon fixfertig
nebst einer Reihe von ALgorithmen (Sortieren...).
Verkettete Liste ist z.B. "vector".

Christoph

christophwth
28-09-2000, 15:20
Hallo

und erstmal Danke für Eure Antworten.

tommy auf Dein Beispiel hin habe ich noch mal in den K&R geschaut
und mir das Kapitel Zeiger auf Strukturen noch mal vor genommen.
" Das mit dem Schreibfehler, *pl im struct und zl in der Fehlermeldung kam
daher,
daß ich zl kurzfristig in pl umgenannt habe.

Zu Deinem Beispiel: Wenn ich das Schlüsselwort struct weglasse ändert sich
nur was wenn ich struct baum vor struct liste im Quelltext stehen habe.
Dann meckert der Präprozessor weil es keinen Datentyp LISTE gibt.

In Deinem Beispiel machst Du die Zugriffe in Main. Ich hingegen übergebe einen Zeiger auf die Struktur an eine Funktion deshalb muß ich noch einmal mehr
dereferenzieren.

Und das geht wohl nur so, printf("%i\n",(*(*node).zl).wert);
wenn ich den Auswahloperator -> benutze Bsp. node->zl->wert kommt eine
Fehlermeldung. Durch Kammerung habe ich es nicht hinbekommen das mit dem
->Operator richtig dereferenziert wurde.

an the "real" Christoph http://www.linuxforen.de/ubb/wink.gif Danke für den Tipp zur Zeit muß ich mich im Rahmen
meiner Klausurvorbereitung mit Standart ANSI C herumschlagen. Also alles auf die
herkömmliche Weise programmieren "huhuu wir dürfen printf benutzen ", http://www.linuxforen.de/ubb/wink.gif kein
Witz, ich kenne noch Semester die mußten sich ihr printf selber schreiben.

Zur C++ Klausur werde ich Deine Vorschläge aber sicherlich mal in die Tat
umsetzen.

Hier sind noch 2 Funktionen die mit der doppelten Dereferenzierung arbeiten

<pre>
KNOTEN *buildtree (LISTE *list, KNOTEN *pnode )
{
if ( pnode != NULL){ /* Baum nach Position durchsuchen */
printf("%i",(*(*pnode).zl).wert); /* zur Kontrolle */
if (list->wert >=(*(*pnode).zl).wert)
pnode->pr=buildtree(list,pnode->pr);

else
pnode->pl=buildtree(list,pnode->pl);
}
else /* Neuen Knoten erzeugen */
{
pnode = (KNOTEN*)malloc(sizeof(KNOTEN));
if (pnode != NULL)
{
pnode->zl=list;
pnode->pl=pnode->pr=NULL;
}
else
printf("\nSpeicherallozierungs-Fehler");
}
return pnode;
}


void printtree(KNOTEN *node )
{

if (node != NULL)
{
printtree(node->pr);
printf("%i\n",(*(*node).zl).wert);
printtree(node->pl);
}
return;
}
</pre>

CU
Christoph

thommy
28-09-2000, 15:32
Hi christophwth,

Wenn der Auswahloperator nicht funktioniert, hast Du einen Fehler drin.
Hier nochmals das kleine Programm (etwas abgeändert, z.B. unbenannte structs):

<pre>
#include &lt;stdio.h&gt;


typedef struct {
int wert ;
struct liste *next;
} LISTE;

typedef struct {
LISTE *zl;
struct knoten *pr;
struct knoten *pl;
}KNOTEN;

int main() {
KNOTEN *pnode;
pnode = (KNOTEN*) malloc (sizeof(KNOTEN));
pnode-&gt;zl = (LISTE*) malloc (sizeof(LISTE));
pnode-&gt;zl-&gt;wert = 10;
printf("%i\n", pnode-&gt;zl-&gt;wert);
return 0;
}
</pre>

'tschuldigung, aber die Zeit, um alles in Funktionen zu packen, habe ich nicht. Hoffe, dass das Prinzip klar ist.

Thomas

christophwth
28-09-2000, 20:21
Hi
Thomas

wenn Du das mit der Funktion gemacht hättest. Dann hättest Du gesehen wo
mein Problem lag. Ich übergebe einen Zeiger und in der Funktion
geht das Bsp: a->b->c nicht weil ich noch mal deferenzieren muß.

Das Programm läuft jetzt.

Gruss
Christoph

thommy
29-09-2000, 06:54
Weiß nicht, wo das Problem ist:

<pre>
...

void printwert ( KNOTEN* pnode )
{
printf("%i\n", pnode->zl->wert);
}

int main() {
KNOTEN *pnode;
pnode = (KNOTEN*) malloc (sizeof(KNOTEN));
pnode->zl = (LISTE*) malloc (sizeof(LISTE));
pnode->zl->wert = 10;
printwert( pnode );
return 0;
}
</pre>

Oder übergibst Du einen Zeiger auf einen Zeiger???
void printwert ( KNOTEN** pnode )
{
printf("%i\n", (*pnode)-&gt;zl-&gt;wert);
}
int main() {
...
printwert( &amp;pnode );
...
}
<pre>
...

</pre>
Thomas

[Dieser Beitrag wurde von thommy am 29. September 2000 editiert.]

thommy
29-09-2000, 12:26
Ob Du benannte oder unbenannte struct's verwendest, sollte für den Compiler keine Rolle spielen. Da Du per typedef ohnehin einen neuen Typ definierst, ist das Benennen der Structs überflüssig.

In Deinen Funktionen erkenne ich auf Anhieb keinen Fehler, also ist das Casting-Problem vermutlich an anderer Stelle zu suchen. Du kannst mir ja das Programm zusenden, vielleicht entdecke ich das Problem (wird aber erst am Montag).

Schönes Wochenende...
Thomas

PS: Zwecks Compiler-Warnungen wäre sinnvoll zu wissen, welchen Compiler Du verwendest?

christophwth
29-09-2000, 23:09
Hi

thommy Du hast recht das Programm funktioniert wenn ich hinter struct die Benennung weglasse. Es treten dann bei der Komplierung nur ein
paar Warnings auf von wegen incompatiple Pointer type
Ich bin jetzt völlig verwirrt. Woran liegt das ??
Will er jetzt noch irgentwas gecasted haben ?
Das mit Zeiger auf Zeiger mache ich nicht wie Du in der oberen Funktion sehen kannst.

nochmal Danke für Deine Hilfe.
CU
Chrsitoph

christophwth
30-09-2000, 23:03
Hallo

tommy
Das Programm ist jetzt noch um eine Funktion erweitert worden, und hat jetzt fast schon Serienreife http://www.linuxforen.de/ubb/wink.gif
Ich habe das Problem mit den Warnings immernoch aber muß mir Die Warnigs noch mal vornehmen vielleicht finde ich Ursache. Die Fehler die mich vorher zur Verzeiflung gebracht habe sind nicht reproduzierbar ?
Vielleicht lags an den CompilerOptions von xwpe dort war standartmäßig
-g eingeschaltet, teilweise sind dann beim ersten Kompliervorgang
Fehler aufgetaucht die nach einem weiterem Kompiliervorgang nicht mehr zu Tage traten ...Hääähh

mein Complierer ist der gcc version 2.95.2 19991024 (release)

Danke für Dein Angebot vielleich komme ich am Montag darauf zurück.


CU und schönes Wochenende

Christoph