【问题标题】:Inserting element in a linked list with Pascal使用 Pascal 在链表中插入元素
【发布时间】:2013-11-20 04:24:04
【问题描述】:

我已经看到一些算法旨在在此处的链接列表末尾附加一个元素并浏览其他网站,然后我编写了一个小程序,我相信它应该在列表末尾附加一个给定元素,但它似乎不起作用。 我的问题是,为什么它不起作用?

我定义的指针和节点如下:

 Pointer = ^Node;
Node = record
    about : element;
    next : Pointer;
end;

下面的过程接收一个链表 L 和一个应该附加到 L 末尾的 q 元素

首先我定义了之后要插入的记录

var INS : Poniter;
........
INS.about := q;

流程如下:

{temp := L}  {I'll use this for my attempt below }
if L<>NIL then
begin
  while L^.next<>NIL do
  begin 
  L:= L^.next;
  end;
  L^.next := INS;
  INS^.next := NIL; 
  {L:=temp;} {I'll explain this in my attempt below}
end
else
 begin
  L:= INS;
 end;

我还有一个打印链表所有元素的小程序

 procedure displayElements(L : pointer);

 begin
  while L <> nil do
  begin
   writeln(L^.about);
   L := L^.next;
   end
 end;

问题:在我运行 de 程序后,它只显示列表的最后两个条目。

关于问题的猜想:我相信它只显示最后两个,因为当我运行过程 displayElements 时,指针 L 已经是 NIL 之前的一个元素 - 因为我使用了第二种算法 -。

尝试解决方案:好的,我认为我需要将 L 放回第一位,这样当我使用 displayElements 时,它会获取列表中的所有元素。但是我怎么能这样做呢?,我尝试了我在上面将 L 保存在 temp 中的评论,但它没有用。

有什么想法吗?谢谢。

【问题讨论】:

  • 插入过程的标题是什么?您是使用插入局部变量还是全局变量?顺便说一句,'INS^.next := NIL' 行应该是你初始化 INS 的地方,你没有显示。您似乎在重新定义“指针”类型也无济于事。
  • 标题:过程插入(q:整数;L:指针)。我同意我应该输入“INS^.next := NIL”,但是我在哪里重新定义了“指针”类型?。
  • 在代码的开头,你写了“我定义了指针和节点如下:指针 = ^node”。

标签: linked-list pascal freepascal


【解决方案1】:

这是一个非常简单的程序,可以满足您的需求。维护一个“尾”指针意味着您不必每次要添加值时都遍历列表。如果这是您的代码,那么您将在 Insert 中丢失 'tail:= tmp' 行:没有这个,Display 会打印第一个和最后一个条目,但不会打印中间的那些。

type
 node = ^MyRec;
 MyRec = record
          value: integer;
          next: node
         end;

var
 head, tail: node;

Procedure Insert (v: integer);
var
 tmp: node;

begin
 new (tmp);
 tmp^.value:= v;
 tmp^.next:= nil;
 if head = nil
  then head:= tmp
  else tail^.next:= tmp;
 tail:= tmp;
end;

Procedure Display;
var
 tmp: node;

begin
 tmp:= head;
 while tmp <> nil do
  begin
   writeln (tmp^.value);
   tmp:= tmp^.next
  end;
end;

begin
 head:= nil;
 Insert (5);
 Insert (10);
 Display;
 Insert (15);
 Display;
 readln
end.

[编辑]

根据您的 cmets 判断,需要进一步解释。 [Professorial mode on] 当我大约三十年前开始编程时(PDP 11/70 上的 OMSI Pascal),链表和指针出现在每个自尊的程序中,但自从 1990 年 Delphi 兴起以来,这些复杂性就被隐藏了而且大多数程序员现在再也看不到裸指针了。

链接列表有不同的格式:简单的和复杂的。简单类型在插入和删除点上有所不同:堆栈在同一端插入和删除,队列在一端插入并在另一端删除,列表允许在任何位置插入和删除。更复杂的类型是树和图。您的问题是关于 queue 的实现 - 插入总是在后面,删除总是在前面。

为了正确实现这一点,我们需要两个变量:'head' 指向队列的头部,'tail' 指向队列的末尾。这些变量是普通的全局变量;在程序的数据段中为它们分配内存。指针是一个简单的变量,其值是另一个变量的内存地址。最初,'head' 不指向任何东西,因此它的值为 nil(将其视为 0)。

通常在教科书中,队列的构造伴随着显示内存分配方式的小框,但我不知道如何做到这一点,所以解释会有点罗嗦。

当第一次插入发生时,运行时系统中的内存管理器从堆中分配 12 个字节,并将局部变量 'tmp' 的值设置为其中第一个的地址12 个字节(这是“新 (tmp)”)。在这 12 个字节中,“值”部分设置为 5,“下一个”部分设置为 nil。然后程序检查'head' 的值是什么:如果它是nil,则将值(即上面分配的内存块的地址)从'tmp' 复制到'head'。如果 'head' 已经指向某个东西,那么 'tmp' 的值将被复制到 'tail^.next' (以前应该是 nil)。然后将 'tmp' 的值复制到 tail 变量中。因此'head'总是指向队列的开头并且不会改变,而'tail'指向队列的末尾并且每次插入新节点时都会改变。

让我们做一些调试:

When the program starts, head = nil, tail is undefined
After 'insert (5)', head = $870874, tail = $870874
After 'insert (10)', head = $870874, tail = $870880 
After 'insert (15)', head = $870874, tail = $87088C

显示时,

tmp:= head ......... tmp = $870874  (ie head)
tmp:= tmp^.next .... tmp = $870880
tmp:= tmp^.next .... tmp = $87088C
tmp:= tmp^.next .... tmp = nil

如果您的程序有多个队列,那么每个队列都需要两个变量,并且必须更改“插入”才能接受两个参数(这将是给定队列的头部和尾部) .

没有必要写'new(head)'和'new(tail)' - 这样做会导致原始指向队列开头和结尾的指针丢失。

[Professorial mode off] 我希望这个解释有帮助。

【讨论】:

  • 非常感谢。对不起,我没有放置 Insert 的标题,但它应该是 Insert(v:integer,L:list),我在给定列表中插入新值,这就是为什么我移动到最后一个元素名单。我又试了一次:(1)new(tail),new(head),new(tmp); (2)head := L [保存列表的第一个值]; (3) while L^.signil do L:= L^.sig [获取最后一个值]; (4) tail := L [保存尾部], (5) tmp.value := v; (6) tmp^.next := nil, (7) tails^.next := tmp;[插入以下值] (8) L:=head [回到第一个]。您的代码有效,但这会返回错误。为什么?谢谢!
  • @Trash: 不要写 'new (tail);新的(头)'。这些应该是指向列表中元素的全局指针,而您每次都在创建新的。尝试绘制一个小方框图,看看列表是如何创建的。
  • 非常感谢!!! :) 我删除了 new(head), new(tails) 并进行了一些小改动,它终于奏效了,现在我可以按照 Polya 的建议完成整个问题,这是“更容易”的情况,因为我必须在根据某些标准列表中的任何点(我已经为它完成了功能)-。我猜想在 [L] 和 [L.next] 之间插入 [INS] 我可以只做 [L]->[INS] 然后 [INS]->[L.next],对吧?非常感谢您的解释,这真的很有帮助!。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-28
  • 2016-04-13
  • 2018-08-02
  • 2016-05-20
相关资源
最近更新 更多