0

私はプログラミングに関してはかなり「グリーン」で、明日課題を提出しなければなりません。ほぼ完成ですが、少し問題があります。最初の要素を削除できません。最初の要素を削除しようとした後、その場所に新しい要素を入力すると、うーん...代わりに無限に多くの要素を入力したとしましょう。何が問題なのかわかりません。前もって感謝します

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.
4

1 に答える 1

0

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

上記の手順の微妙な結果の 1 つは、リストの最後のノードを削除すると、firstNode と lastNode の両方が null に設定されるため、1 要素リストからの最後のノードの削除を正しく処理することです。

個別の「removeBefore」または「removeAfter」メソッドも必要ないことに注意してください。二重にリンクされたリストでは、「remove(node.prev)」または「remove(node.next)」が有効な場合にのみ使用できるためです。

これは、削除されるノードが存在することが保証されていることも前提としています。

ノードがこのリストに存在しない場合は、何らかのエラー処理が必要になります。

于 2012-03-14T19:42:21.427 に答える