Войти

Показать полную графическую версию : Стек, заданный списком, на Паскале.


ManHack
31-03-2009, 20:02
Есть стек, который задаётся списком (т.е. с динамическими переменными, а не через массив).
Т.к. стек действует по принципу LIFO, в нём элементы списка должны записаться в обратном порядке.
Вопрос: как вывести стек на экран? (как вывести список - понятно, нужно вывести именно стек)

Busla
31-03-2009, 21:21
А вот фигушки - ничего не ответим, пока не покажешь решения Паскаль и NaN (http://forum.oszone.net/thread-128870.html)! :tongue:

ManHack
31-03-2009, 21:36
http://www.animereactor.ru/forum/style_emoticons/default/catty26.gif

pva
01-04-2009, 12:33
нужно вывести именно стек »
В чём отличие при выводе стека и списка?

ManHack
01-04-2009, 15:21
Список выводит элементы попорядку, а стек - в обратном порядке.

type
tData = integer;
tPtr = ^tNode;
tNode = record
data: tData;
next: tPtr;
end;
tStack = record
first, last: tPtr;
end;

var
S: tStack;
D: tData;


function NotEmpty (var S: tStack): boolean; {проверка стека на пустоту}
begin
NotEmpty := S.First <> nil;
end;

procedure Build (var S: tStack; D: tData); {первоначальное заполнение стека}
var
f: text;
p: tPtr;
begin
assign (f,'stack.txt');
reset (f);
S.First := nil;
S.Last := nil;
while not eof(f) do begin
New(p);
readln (f, D);
p^.data := D;
if S.First = nil then
S.First := p
else
S.Last^.next := p;
S.Last := p;
end;
close(f);
end;

procedure Push (var S: tStack; D: tData); {добавить элемент}
var
p: tPtr;
begin
write ('Item = ');
readln (D);
New(p);
p^.data := D;
S.Last^.next := p;
D := 0;
end;

procedure Pop (var S: tStack; var D: tData); {изъять элемент}
var
p: tPtr;
begin
if NotEmpty(S) then begin
D := S.Last^.data;
p^ := S.Last^;
S.Last := S.Last^.next;
p^.next := nil;
{ Dispose(p); }
end;
end;

procedure Clear;
begin
end;

procedure Echo (S: tStack); {вывод стека на экран}
var
p: tPtr;
begin
{p^ := S.Last^;}
while S.Last <> nil do begin
Pop (S, D);
writeln (D);
Echo (S);
end;

end;

В данном случае ECHO возвращает последний элемент стека и два нолика.
Почему?
Может я и правда каких-то серьёзных ошибок в этом коде не вижу?
Если что, хотелось бы пользоваться только p^.next, а p^.prev не пользоваться ^^

pva
01-04-2009, 20:59
ну так действия такие:
вариант 1:
1. загнать всё в массив (задом-наперёд)
2. вывести массив на экран (передом-назад)
вариант 2:
перевернуть монитор вниз-головой или смириться с ситуацией любым другим образом. Например пусть есть таблица логов. Её можно отрисовать по возрастанию даты, а можно по убыванию - так даже удобней будет.

Alan85
01-04-2009, 21:44
Принципиально не верно стек сделан - последний элемент должен хранить адрес предыдущего т.е. 1<-2<-3<-4... а тут 1->2->3->4. Поэтому после выдавливания последнего элемента указатель last теряется... - адреса 3 элемента не найдет (если только перебором от 1 до 3).
Вот как подправил я:

procedure Build (var S: tStack; D: tData); {первоначальное заполнение стека}
var
f: text;
p: tPtr;
begin
assign (f,'stack.txt');
reset (f);
S.First := nil;
S.Last := nil;
while not eof(f) do begin
New(p);
readln (f, D);
p^.data := D;
if S.First = nil then begin
S.First := p; s.last:=p end
else
begin
p^.next := s.last;
S.Last := p;
end;
end;

close(f);
end;

procedure Echo (var S: tStack); {вывод стека на экран}
var
p: tPtr;
begin
{p^ := S.Last^;}
while S.last <> s.first do begin
Pop (S, D);
write (D,' ');
// Echo (S);
end;
Pop (S, D);
write (D,' ');
end;

Но это стирает стек - полностью его выталкивает, поэтому для отображения не верно все же :)

Busla
01-04-2009, 23:37
Если надо исключительно через стек реализовать, то создать второй и перепихать в него результаты - получится обратный порядок. Эффективнее, конечно же, решать задачу не через стек.

Alan85, а если не стирает - это уже не стек ;)

Alan85
02-04-2009, 07:52
Не ну одно дело вывести содержимое (посмотреть) а другое выкинуть его весь.. а вообще я бы все переписал с нуля - реально не уютно этим кодом пользоваться- интуиция. Да и процедуру push тоже надо переписать если идти от конца к началу.

ManHack
07-04-2009, 23:48
А как идти от конца к началу?




© OSzone.net 2001-2012