2017-02-13 52 views
1

所以我有这堆巨大的代码,但它不会正常工作。而且我不确定一个清单是如何工作的。任何人都可以向我提出正确的方向,谁擅长这一点?非常感谢:)为什么我的双向链表不起作用? (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. 

就忽略结束部分,我知道,它不会产生正确的结果呢,只是功能“traverselist”有趣的是

+0

你的列表覆盖每次迭代是不是? – Emiliano

回答

1

我想你的类型声明,你已经到了一个无望的混乱。首先要做的就是把它排除,然后你应该发现其余的很简单。

我想你打算在你的链接列表中的条目是Pokemon类型的,但如果你把它叫做一个PokemonNode的原因,我会解释更直观..

现在,一个单向链表是实际上是一个非常简单的结构:它由一系列节点组成,每个节点都包含数据字段(在您的案例中为PokemonName和PokemonPosition)以及指向列表中下一个条目的指针。

双向链表就像一个单链表,除了每个节点还有一个指向列表中前一个节点的指针以及下一个节点。

所以,你想要定义两件事情,一个是PokemonNode,它是列表中的单个条目,还有一个PokemonPointer,它可以指向一个Pokemon节点。您在帕斯卡尔这些声明的方式是这样的:

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

顺便说一句,我选择了这些名字,PokemonNode和PokemonPointer所以如果你用我的更换你的TYPE声明,你将不得不通过所有代码并对其进行更改,但更重要的是,您必须考虑您要对节点和列表执行的操作。

我想你可以自己做剩下的,但是如果你卡住了,问问。在您习惯于考虑列表节点之前,您可能会发现绘制和标记代表创建和插入新节点的图片并删除它们会有所帮助。

您可能会发现有用的一个提示是将您的列表写入循环列表(换句话说,列表中最后一个条目的Next指针指向列表中的第一个条目,这样可以避免您的代码需要在你做某些事情之前,要继续检查下一个节点是否为Nil,而只需要使用指向它的指针来跟踪列表的开始。

+0

哇,真棒!多数民众赞成在一个伟大的想法,我会明天尝试这个!t – user7285912