双向链表显示异常:除首个添加元素外其余元素呈逆序
Pascal双向链表显示逆序及删除异常问题修复
我编写了一段实现双向链表添加、删除、显示操作的Pascal代码,现在遇到两个问题:
- 显示链表时,除第一个添加的元素外,其余元素均呈逆序排列;
- 尝试在
pridej(添加)过程末尾添加akt := novy后,uber(删除)过程无法正常工作。
原代码如下:
program obecny_seznam; {$APPTYPE CONSOLE} uses SysUtils; type ppolozka = ^tpolozka; tpolozka = record H: integer; prev,next: ppolozka; end; var poc, pom, pom2, novy, akt: ppolozka; //-------------------------------------------------------- procedure pridej; //add begin if (poc = nil) and (akt = nil) then begin new(novy); readln(novy^.H); novy^.next := nil; novy^.prev := nil; poc := novy; akt := novy; end else if akt^.next = nil then begin new(novy); readln(novy^.H); novy^.prev := nil; novy^.next := nil; akt^.next := novy; novy^.prev := akt; end else begin pom := akt^.next; new(novy); readln(novy^.H); novy^.prev := nil; novy^.next := nil; pom^.prev := novy; novy^.next := pom; novy^.prev := akt; akt^.next := novy; end; end; //-------------------------------------------------------- //-------------------------------------------------------- procedure uber; //remove begin if poc = nil then writeln('Seznam je prazdny.') else if akt^.next = nil then begin dispose(poc); akt := nil; poc := nil; end else if (akt^.prev = nil) then begin pom := akt; akt := akt^.next; akt^.prev := nil; dispose(pom); poc := akt; end else begin pom := akt^.prev; pom2 := akt^.next; pom^.next := pom2; pom2^.prev := pom; dispose(akt); akt := pom2; end; end; //-------------------------------------------------------- //-------------------------------------------------------- procedure zobraz; //display begin pom := poc; if pom <> nil then begin while pom <> nil do begin if pom = akt then writeln('*', pom^.H) else writeln(pom^.H); pom := pom^.next; end; end else writeln('Zasobnik je prazdny.'); end; //-------------------------------------------------------- begin poc := nil; akt := nil; pridej; pridej; pridej; pridej; readln; zobraz; uber; readln; zobraz; readln; end.
问题根源
- 添加逻辑错误:原
pridej过程中,当akt^.next不为空时,会在akt和它的下一个节点之间插入新元素,而非将新元素追加到链表末尾。比如依次添加1、2、3时,第二次添加2到末尾后akt仍指向1,第三次添加3时会插入到1和2之间,导致链表顺序变为1→3→2,后续添加重复此逻辑,最终显示时出现逆序。 - 删除逻辑错误:原
uber过程中,当akt是最后一个节点时,错误地释放了头节点poc,而非当前akt节点,导致整个链表被破坏,后续操作崩溃。
修复方案
1. 修正pridej过程(改为末尾追加元素)
修改后的pridej过程统一将新元素追加到链表末尾,同时让akt指向新添加的节点,保证后续添加操作的连贯性:
procedure pridej; //add begin new(novy); readln(novy^.H); novy^.prev := nil; novy^.next := nil; if poc = nil then // 链表为空时初始化 begin poc := novy; akt := novy; end else // 链表非空,追加到末尾 begin pom := poc; // 遍历找到最后一个节点 while pom^.next <> nil do pom := pom^.next; // 挂载新节点 pom^.next := novy; novy^.prev := pom; akt := novy; // 更新akt为新节点 end; end;
2. 修正uber过程(修复删除逻辑)
修改后的uber过程正确处理各种节点的删除场景,尤其是最后一个节点的删除逻辑:
procedure uber; //remove begin if poc = nil then writeln('Seznam je prazdny.') else if poc = akt then // 唯一节点的情况 begin dispose(akt); akt := nil; poc := nil; end else if akt^.next = nil then // 删除最后一个节点 begin pom := akt^.prev; pom^.next := nil; dispose(akt); akt := pom; // 删除后akt指向前一个节点 end else if akt^.prev = nil then // 删除头节点(非唯一) begin pom := akt; akt := akt^.next; akt^.prev := nil; dispose(pom); poc := akt; end else // 删除中间节点 begin pom := akt^.prev; pom2 := akt^.next; pom^.next := pom2; pom2^.prev := pom; dispose(akt); akt := pom2; end; end;
验证效果
修改后,依次添加1、2、3、4,链表顺序为1→2→3→4,显示完全正常;执行删除操作后,当前节点被正确移除,链表结构保持完整,后续显示和操作均正常。
内容的提问来源于stack exchange,提问作者Adriana
相关产品推荐
相关产品推荐

