2017-02-13 4 views
1

donc j'ai cet énorme tas de code, mais ça ne marchera pas correctement. Et je ne suis pas sûr de la façon dont une liste fonctionne exactement. Quelqu'un peut-il m'indiquer à la bonne direction qui est bon à cela? MERCI BEAUCOUP :)Pourquoi ma liste à double liaison ne fonctionne-t-elle pas? (Pascal)

Program ListendDerHoelle; 

Uses CRT; 

TYPE 
    Pokemon = ^pointer; 
    pointer = 
    RECORD 
     PokemonName : STRING[30]; 
     PokemonPosition : INTEGER; 
     Next : Pokemon; 
     Prev : Pokemon; 
    END; 
VAR Liste, Eintrag, head: Pokemon; 

FUNCTION TraverseList(AddPokemonPosition : INTEGER) : Boolean; FORWARD; 
PROCEDURE Ausgabe(i: Integer); FORWARD; 
PROCEDURE Abfrage; 
VAR PokemonName2 : STRING[30]; 
    PokemonPosition2, Anzahl, i : Integer; 

BEGIN 

    Liste := NIL; 
    Eintrag := NIL; 

    Anzahl := 99; 

    Writeln('Wie viele Pokemon einspeichern?'); 
    Writeln; 
    Readln(Anzahl); 

    FOR i := 1 TO Anzahl DO 
    BEGIN 
     ClrScr; 
     Writeln('Pokemon Name:'); 
     Writeln; 
     Readln(PokemonName2); 
     ClrScr; 
     Writeln('Pokemon Position:'); 
     Writeln; 
     Readln(PokemonPosition2); 
     ClrScr; 

     New(Eintrag); 
     Eintrag^.Next := NIL; 
     Eintrag^.Prev := NIL; 

     IF TraverseList(PokemonPosition2) = TRUE THEN 
     BEGIN 
       Eintrag^.PokemonName := PokemonName2; 
       Eintrag^.PokemonPosition := PokemonPosition2; 
       Liste := Eintrag; 
     END 
     ELSE 
     BEGIN 
      Writeln('Position nicht gefunden. Das Ende der Welt steht unmittelbar bevor!'); 
     END; 
    END; 

    Ausgabe(Anzahl); 


END; 
FUNCTION TraverseList(AddPokemonPosition : INTEGER) : Boolean; // Wenn die Funktion also True zurückgibt, ist das Element gefunden! 
VAR vElementFound : Boolean; 
BEGIN 

    vElementFound := FALSE; 
     TraverseList := FALSE; 


    WHILE (vElementFound = FALSE) DO 
    BEGIN 

        IF (Liste = NIL) THEN // wenn es das erste Element ist 
        BEGIN 
         vElementFound := TRUE; 
         Head := Liste; 
        END 

        ELSE IF ((Liste^.Next = NIL) AND (vElementFound = FALSE)) THEN  // wenn es das letzte Element ist 
        BEGIN 
         Liste := Liste^.Next; 
         vElementFound := TRUE; 
        END 
        ELSE IF (vElementFound = FALSE) THEN // ansonsten 
        BEGIN 
         IF (Eintrag^.PokemonPosition < AddPokemonPosition) AND NOT (Eintrag^.Next^.PokemonPosition > AddPokemonPosition) THEN 
         BEGIN 
           Liste := Liste^.Next; 
         END 
         ELSE IF (Eintrag^.PokemonPosition > AddPokemonPosition) AND NOT (Eintrag^.Prev^.PokemonPosition > AddPokemonPosition) THEN 
         BEGIN 
           Liste := Liste^.Prev; 
         END 
         ELSE 
         BEGIN 
          vElementFound := TRUE; 
         END; 
        END; 
    END; 

    IF (vElementFound = TRUE) THEN 
     BEGIN 
       TraverseList := TRUE; 
     END; 

END; 
PROCEDURE Ausgabe(i : Integer); 
var a : Integer; 
BEGIN 
     Liste := Head; 
     FOR a := 1 TO i DO BEGIN 


     Writeln(Eintrag^.PokemonName, ' ', Eintrag^.PokemonPosition); 
     Liste := Liste^.Next; 
     Readkey; 


     end; 


END; 



BEGIN 
Abfrage(); 
END. 

ignorer la partie terminale, je sais que ce produit habitude les bons résultats encore, juste la fonction « traverselist » est intéressant

+0

votre liste est prioritaire à chaque itération n'est-ce pas? – Emiliano

Répondre

1

Je pense que votre déclaration de type vous a obtenu en une confusion désespérée. La première chose à faire est de faire le tri, et ensuite vous devriez trouver le reste très simple.

Je pense que vous avez l'intention les entrées de votre liste chaînée à être de type Pokemon, mais il est plus clair si vous appelez un PokemonNode pour des raisons que j'expliquerai ..

Maintenant, une liste simplement chaînée est en fait une structure très simple: elle consiste en une série de nœuds qui contiennent chacun des champs de données (dans votre cas PokemonName et PokemonPosition) et un pointeur vers l'entrée suivante dans la liste. Une liste à double liaison est semblable à une liste à liaison unique, sauf que chaque nœud a également un pointeur vers le nœud précédent dans la liste ainsi que vers le suivant. Donc, vous voulez définir deux choses, un PokemonNode, qui est une seule entrée dans la liste, et un PokemonPointer qui est un pointeur qui peut pointer vers un nœud Pokemon. La façon dont vous déclarez ces Pascal est comme ceci:

TYPE 
    PokemonPointer = ^PokemonNode; 
    PokemonNode = 
    RECORD 
     PokemonName : STRING[30]; 
     PokemonPosition : INTEGER; 
     Next : PokemonPointer; 
     Prev : PokemonPointer; 
    END; 

BTW, j'ai choisi ces noms, PokemonNode et PokemonPointer de sorte que si vous remplacez votre déclaration de type avec le mien, vous devrez passer par tout votre code et changez-le, mais plus important encore, vous devez penser à ce que vous essayez de faire avec le nœud et la liste.

Je pense que vous serez en mesure de faire le reste vous-même, mais si vous êtes coincé, demandez. Jusqu'à ce que vous ayez l'habitude de penser aux nœuds de liste, vous pourriez trouver utile de dessiner et d'étiqueter des images qui représentent la création et l'insertion d'un nouveau nœud et la suppression d'un nœud. Un conseil que vous pouvez trouver utile est d'écrire votre liste en tant que circulaire (en d'autres termes, le pointeur Next de la dernière entrée de la liste pointe vers la première entrée de la liste. Continuez à vérifier si le nœud suivant est nul avant de faire quelque chose, mais il vous suffit de suivre le début de la liste en utilisant un pointeur pointé dessus

+0

wow, génial! Thats une bonne idée, je vais essayer cela demain! T – user7285912