PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Mehrere Verkettete Listen in C



DanDanger
16-10-2003, 21:53
Hallo,

ich hab da ein kleines Listen-Problem in C :

Ich habe folgendes Listen-Element :


struct Sektor
{
unsigned int SektorID ;

FigList *FigurenListe ;
Sektor *Next ;
}


Das Problem ist : Jedes Element der "Sektor-Liste" soll nun seinerseits eine Liste
mit anderen Objekten (hier : FigurenListe) Verwalten.

Eine "normale" Verkettete Liste in C zu erstellen ist ja kein Problem,
aber hier habe ich das Problem, das ich keinen "Cursor" verwenden kann,
um in der FigurenListe zu Navigieren, da es ja mehrereFiguren-Listen gibt.

MeineFrage : Was kan ich tun ??

quinte17
17-10-2003, 07:02
dass läuft auch nicht anders als eine normale verkettete liste... nur du musst halt deinen anfangspointer auf das gleiche objekt zeigen lassen wo dein figurenlistenpointer hinzeigt

sector-figurenliste-figurenliste-figurenliste
|
sector-figurenliste-figurenliste
|
sector-figurenliste-figurenliste-figurenliste-figurenliste-figurenliste-figurenliste


deine liste sollte ja dann so aussehen
du brauchst einmal eine steuerung die die sectoren verwalltet, da brauchst du ja einen statischen pointer der zumindest immer auf dass erste element zeigt (da du ja sonst die elemente im ramnirvana verlierst... und du brauchst noch einen "dynamischen" pointer den du bei jedem sector element neu auf dass erste figurenelement zeigen lässt (also immer neu zuweisen musst)

dass is der einzige unterschied zu einer normalen liste

wenn du sonst noch fragen hast schreib einfach ;)
greetz

DanDanger
18-10-2003, 14:20
du brauchst einmal eine steuerung die die sectoren verwalltet, da brauchst du ja einen statischen pointer der zumindest immer auf dass erste element zeigt (da du ja sonst die elemente im ramnirvana verlierst... und du brauchst noch einen "dynamischen" pointer den du bei jedem sector element neu auf dass erste figurenelement zeigen lässt (also immer neu zuweisen musst)


Genau da liegt ja mein Problem :
ich weiss nicht wie ich das mit dem statischen Pointer machen soll.
Bisher hatte ich das immer so gelöst :


struct Sektor
{
......
} ;

Sektor *ErstesElement, *LetztesElement, *Cursor ;


Das anhängen von Elementen sah dann immer so aus :


void ElementAnhaengen()
{
Sektor *NeuesElement = malloc(sizeof(*Sekor)) ;

LetztesElement->Next = NeuesElement ;
........
LetztesElement = NeuesElement ;
NeuesElement->Next = NULL ;
.....
}


Das Problem ist ja, dass ich den Cursor zum durchlaufen der Liste brauche,
und LetztesElement und ErstesElement als indikatoren für den Listen Anfang und Ende.
Diese sind jedoch nur EINMAL vorhanden, so dass ich nur EINE Liste Verwalten kann, und nicht beliebig viele.....

Neugierige Grüsse
DanDanger

anda_skoa
18-10-2003, 14:40
Du brauchst nur in deinen Elemente der ersten Liste eine ähnliche Struktur aufbauen.



struct Sektor
{
unsigned int SektorID ;

FigList *FigurenListeAnfang ;
FigList *FigurenListeEnde ;
FigList *FigurenListeCursor ;

Sektor *Next ;
}


Ciao,
_

DanDanger
19-10-2003, 13:58
Hmm, irgendwie krieg' ichs nicht hin :rolleyes:

Ich Poste Euch mal meinen Code :

Also: hier sind die Strukte :


struct Sektor ;
struct SektorList ;

typedef struct Sektor *SektorPtr ;
typedef struct SektorList *SektorListPtr ;

struct Sektor
{
unsigned int SektorID ;
SektorPtr Next ;
} ;

struct SektorList
{
SektorPtr Start, End, Cursor ;
} ;


So, und hier die Implementierung einiger Funktionen :


void SektorAppend /* Haengt ein Element ans Ende der Liste an */
(
SektorListPtr List
)
{
SektorPtr NewNode = malloc(sizeof(*List)) ;

if(!NewNode)
{
printf("FEHLER : Kann kein Element in die Liste Einfuegen \n") ;
printf("Programm wird jetzt Abgebrochen \n") ;
exit(1) ;
}

NewNode->Next = NULL ;

/* Ich glaube, in der IF-Abfrage liegt der Fehler */
if(List->End != NULL) /* Noch Kein Element in der Liste => Erstes Element Erzeugen */
{
NewNode->SektorID = 0 ;
List->Start = NewNode ;
List->End = NewNode ;
}
else
{
NewNode->SektorID = (List->End->SektorID) + 1 ;
List->End->Next = NewNode ;
}
List->Cursor = NewNode ;
List->End = NewNode ;
}

/*********************
SektorNext
*********************/
void SektorNext
(
SektorListPtr List
)
{
List->Cursor = List->Cursor->Next ;
}

/*********************
SektorGotoStart
*********************/
void SektorGotoStart
(
SektorListPtr List
)
{
List->Cursor = List->Start ;
}


Wenn ich das im main-File teste, z.B. mit :


SektorListPtr Liste ;

SektorAppend(&Liste) ;
SektorAppend(&Liste) ;

SektorGotoStart(&Liste) ;
printf("Ausgabe : ") ;
printf("Listenelement : %i \n", (&Liste->Cursor->SektorID)) ;

SektorNext(&Liste) ;
printf("Listenelement : %i \n", &Liste->Cursor->SektorID) ;


gibt's Speicherzugriffsfehler ohne Ende.......

Ich glaube, der Test, ob schon Elemente in der Liste enthalten sind, ergibt immer TRUE, aber ich hab' keine Ahnung, wie ich das sonst testen soll...

Was läuft hier Falsch ????

Neugierige Grüsse
DanDanger

anda_skoa
19-10-2003, 14:26
Liste in main ist ein uninitialisierter Pointer.
Du musst dort noch eine Liste erzeugen.

Ciao,
_

DanDanger
19-10-2003, 18:10
Hi,

so richtig funzt das immer noch nicht :-((
Der Speicherzugriffsfehler ist zwar weg, aber Ansonsten spuckt mein Proggi nur Blödsinn aus...

Ich hab meine main nun so abgeändert :


SektorListPtr Liste = NULL ;

SektorAppend(&Liste) ;
SektorAppend(&Liste) ;
........

printf("Ausgabe der Liste \n") ;

SektorGotoStart(&Liste) ;
printf("Ausgabe : ") ;
printf("Listenelement : %i \n", &Liste->Cursor->SektorID)) ;

........


Die SektorID die Augegeben wird, soll bei jedem Anlegen eines Neuen
Elements Automatisch angelegt werden (siehe vorheriges Post).

Wenn ich mein Proggi nun Durchlaufen lasse, bekomme ich folgende
Ausgabe :


Ausgabe der Liste
Ausgabe : Listenelement : -842150451
Listenelement : -842150451
Listenelement : -842150451
Listenelement : -842150451
Listenelement : -842150451
########################
Listenelement : -842150451
Listenelement : -842150451
...OK


Das sieht mir ganz nach irgendwelchen Speiceradressen, oder uninitialisierten Variabeln aus,
aber ich kann mir nicht erklären, was da genau schief läuft.

Währe nett, wenn Ihr mir da nochmal helfen könntet.....

Neugierige Grüsse
DanDanger

anda_skoa
19-10-2003, 19:03
Original geschrieben von DanDanger
so richtig funzt das immer noch nicht :-((
Der Speicherzugriffsfehler ist zwar weg, aber Ansonsten spuckt mein Proggi nur Blödsinn aus...

Ich hab meine main nun so abgeändert :

Liste ist weiterhin kein Datenelement sondern halt jetzt ein Nullpointer.
Wenn SecktoAppend nachwievor gleich ist, sollte also immer noch ein Segfault kommen, weil List->End eine Dereferenzierung eines Nullpointers ist.

Bau zuerst mal eine normale Liste auf, zb mit einem int als Nutzdaten.
Dann erweitern wir das auf eine Liste als Nutzdaten.

Ciao,
_

DanDanger
20-10-2003, 13:40
@anda_skoa :
Irgendwie Verstehe ich nicht, was Du willst.....
Wie genau muss ich den die Liste (oder den Listenzeiger) initialisieren ?
Kannst Du das vileicht mal als Code-Schnipsel Posten ???

Ich hab"s mal mit :


Sektor NewSektor ;
NewSektor.SektorID = 0 ;

SektorListPtr Liste = *NewSektor ;

versucht, aber so geht"s halt auch nicht.....

Neugierigr Gruesse
DanDanger

quinte17
20-10-2003, 14:30
du kannst doch eine normale liste machen oder etwa nicht?

die wir dann einmal initialiesiert ala

struct andereliste {
int a;
andereliste *next;
}

struct liste {
int test;
andereliste *x;
liste *next = null;
}

liste x;
andereliste y;
liste *listeanfang = &x;
liste *listeende = null??; // kommt drauf an ob die wirklich eine 2 gleisige liste hast
liste *listeaktuelleselement = &x;

so nun brauchst du nochmal mindestens 2 zeiger für die andere interne liste also:
andereliste *anfang = &listeaktuelleselement.x;
andereliste *aktuell = &anfang;

so und wenn du nun in der liste "liste" dass element wechselst, dann musst du auch im gleichen zug die 2 pointer ändern die für "andereliste" zuständig sind... also du hast 2 einfach listen, nur dass du bei der 2. immer wieder die pointer auf den anfang NEU setzen musst...

ich weiß jetzt nicht was daran so schwer ist....
wir werden dir hier warscheinlich nicht alles vorkauen (ich zumindest nicht, will ja nicht für alle sprechen)

lies dir des ein paarmal durch und programmier des halt einmal testweise in einem kleinen umfang durch...

greetz