Reputation: 1
I wrote this code where you can add or remove numbers from a list, and then display the list. The problem is: it displays the numbers in reverse order, except for the first added number.
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.
I don't know what else to change. If I add akt := novy
at the end of procedure pridej
(add) then procedure uber
(remove) doesn't work anymore.
Upvotes: 0
Views: 177
Reputation: 6174
Let's look at the most problematic pieces:
procedure pridej; //add ... else begin pom := akt^.next;
Whenever you read this portion keep in mind that akt
still sticks with the 1st item in your list. This logic doesn't even work then adding a 3rd item anymore, because (akt=1st).next is always the 2nd item. Always.
... pom^.prev := novy; novy^.next := pom;
Now this doesn't make sense: some item's previous (left) member should be the new item? No wonder that you sort everything in front of the existing items. Likewise the new item's next (right) member shouldn't need to be assigned if it is supposed to be the last item.
novy^.prev := akt; akt^.next := novy; end; end;
This is wrong, as it voids the sense of having akt
at all: either you leave it untouched, or you move it along with any item addition. That's why I wrote "try it first without any akt
at all".
Where's the fundamental flaw? You nowhere store the last item of your list, only its first item. If you would also store the last one, you could easily add a new item after that and assign that new item as the last one. Such a variable is missing at all.
You can work without such a variable, but then you have to go from your first list item over .next
in a loop until .next = nil
to find the last item of your list. Have a read on the Wikipedia article on doubly linked lists which also mentions this concept.
Upvotes: 3