为什么我的双向链表不起作用? (帕斯卡)

时间:2017-02-13 19:03:24

标签: 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”很有意思

1 个答案:

答案 0 :(得分:1)

我认为你的TYPE声明让你陷入绝望之中。要做的第一件事就是对它进行排序,然后你应该发现其余部分非常简单。

我认为您希望链接列表中的条目属于Pokemon类型,但如果您将其称为PokemonNode,则会更清楚,原因我会解释..

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

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

所以,你想要定义两个东西,一个PokemonNode,它是列表中的一个条目,还有一个PokemonPointer,它是一个可以指向Pokemon节点的指针。你在Pascal中声明这些的方式是这样的:

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

顺便说一下,我选择了这些名字,PokemonNode和PokemonPointer,这样如果你用我的TYPE声明替换你的TYPE声明,你将不得不查看所有代码并进行更改,但更重要的是你必须考虑你的内容正在尝试处理节点和列表。

我认为你自己可以做其余的事,但如果你遇到困难,请问。在您习惯于考虑列表节点之前,您可能会发现绘制和标记代表新节点的创建+插入以及删除一个节点的图片会很有帮助。

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