我在编程方面相当"新手",明天我必须带上作业。它几乎完成了,但有一个小问题。我无法删除第一个元素,如果在尝试删除第一个元件后,我输入一个新的在它的位置mmm。。。。比方说我输入了无限多的它们。我似乎找不出问题出在哪里。提前感谢
program dvipsar;
type duomenys = integer;
sarasas = ^elementas;
elementas = record
info: duomenys;
anks: sarasas;
tolsn: sarasas
end;
procedure sukurtiTuscia(var s: sarasas); {creates empty list}
begin
s := nil
end;
function tuscias(s: sarasas): boolean; {checks if list is empty}
begin
tuscias := s = nil
end;
function elmSk(s: sarasas): integer; {counts elements}
var kiek: integer;
begin
kiek := 0;
while s <> nil do
begin
kiek := kiek + 1;
s := s^.tolsn
end;
elmSk := kiek
end;
function gautiRodN(s: sarasas; n:integer): sarasas; {Arrow to n-th element}
var i: integer;
begin
i := 1;
while (s <> nil) and (i<n) do
begin
i := i + 1;
s := s^.tolsn
end;
if i = n then gautiRodN := s
else gautiRodN := nil
end;
function gautiN(s: sarasas; n:integer): duomenys; {gets n-th element data}
var elem: sarasas;
begin
elem := gautiRodN(s,n);
if elem <> nil then gautiN := elem^.info
end;
procedure iterptiPries(s:sarasas; n: integer; duom: duomenys); {adds new element before n-th element}
var nElem: sarasas;
naujas: sarasas;
begin
nElem := gautiRodN(s,n);
if nElem <> nil then begin
new (naujas);
naujas^.info := duom;
naujas^.tolsn := nElem;
naujas^.anks := nElem^.anks;
if nElem^.anks <> nil then nElem^.anks^.tolsn := naujas;
nElem^.anks := naujas;
end
end;
procedure panaikintiN(s: sarasas; n: integer); {removes element from n-th place}
var nElem: sarasas;
begin
nElem := gautiRodN(s,n);
if nElem <> nil then begin
if nElem^.anks <> nil then nElem^.anks^.tolsn := nElem^.tolsn;
if nElem^.tolsn <> nil then nElem^.tolsn^.anks := nElem^.anks;
dispose(nElem);
end;
end;
function rasti(s: sarasas; duom: duomenys): sarasas; {finds element}
begin
while (s <> nil) and (s^.info <> duom) do s := s^.tolsn;
rasti := s
end;
procedure spausdinti(s: sarasas); {prints list}
begin
while (s <> nil) do begin
write(s^.info,' ');
s := s^.tolsn
end;
writeln
end;
procedure panaikintiP(var s: sarasas); {removes first element}
var pirmas: sarasas;
begin
pirmas := s;
s := s^.tolsn;
dispose (pirmas)
end;
procedure panaikinti(var s: sarasas); {deletes list}
begin
while s <> nil do panaikintiP(s)
end;
procedure prideti(var s: sarasas; duom: duomenys); {add element at the end of the list}
var kiek: integer;
paskutinis,naujas: sarasas;
begin
kiek := elmSk(s);
paskutinis := gautiRodN(s,kiek);
new(naujas);
naujas^.info := duom;
naujas^.tolsn := nil;
naujas^.anks := paskutinis;
if paskutinis <> nil then paskutinis^.tolsn := naujas
else s := naujas
end;
procedure menu;
begin
writeln;
writeln;
writeln ('1 Creat a list');
writeln ('2 Count the elements');
writeln ('3 Check if list is empty');
writeln ('4 Print an element');
writeln ('5 Print the list');
writeln ('6 Remove an element')
writeln ('7 Add an element');
writeln ('8 Search in the list');
writeln;
writeln ('0 End');
writeln;
writeln;
end;
var s: sarasas;
i,j: integer;
t: sarasas;
c: char;
veiksmas: integer;
begin
sukurtiTuscia(s);
repeat
menu;
write('Input action number : ');
readln(veiksmas);
case veiksmas of
1:
repeat
write('input a number which you want to add to the list: ');
readln(i);
prideti(s,i);
write('Add new number? (t/n)? ');
read(c);
until (c='N') or (c='n');
2: writeln ('List is not empty: ',elmSk(s));
3: if tuscias(s) then writeln ('List is empty')
else writeln ('List is not empty');
4: begin
write ('Which element to print?: ');
readln(i);
writeln(i,'-th list element?: ',gautiN(s,i));
end;
5: spausdinti(s);
6: begin
write ('which element to remove?: ');
readln(i);
panaikintiN(s,i);
end;
7:begin
write ('What to add to the list?: ');
readln(i);
write ('Before which element?: ');
readln(j);
iterptiPries(s,j,i);
end;
8: begin
write ('What element to look for?: ');
readln(i);
t := rasti(s,i);
if t <> nil then writeln (i, ' exists in the list')
else writeln (i, ' does not exists in the list');
end;
0: writeln ('Ending');
else writeln('Incorrect action');
end;
until veiksmas = 0;
panaikinti(s); {deletes list}
end.
http://en.wikipedia.org/wiki/Doubly_linked_list#Removing_a_node
删除节点比插入节点更容易,但如果要删除的节点是firstNode或lastNode:,则需要特殊处理
function remove(List list, Node node)
if node.prev == null
list.firstNode := node.next
else
node.prev.next := node.next
if node.next == null
list.lastNode := node.prev
else
node.next.prev := node.prev
destroy node
上述过程的一个微妙结果是,删除列表的最后一个节点会将firstNode和lastNode都设置为null,因此它可以正确地处理从单元素列表中删除最后一个结点的问题。
请注意,我们也不需要单独的"removeBfore"或"removeAfter"方法,因为在双链表中,我们可以只使用"remove(node.prev)"或"remove(node.next)",这些方法都是有效的。
这也假定被删除的节点是保证存在的。
如果该节点不在此列表中,则需要进行一些错误处理。