|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
|||
|
|||
Реализация очереди через указатели
Возникла проблема в курсовой. В постановке задачи было сказано реализовать очередь, используя только указатели (т.е. не через массивы и т.д.). Вот ,что у меня получилось:
Код:
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, Grids, StdCtrls; type TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; PElement= ^TElement; TElement = record FValue: integer; FNext: Pelement; end; Queue = class(Tobject) private public procedure Push(Value:integer); function Pop():integer; function GetValue():integer; function IsEmpty():boolean; constructor QueueCreate(Value:integer); end; var Form1: TForm1; Queue1: Queue; Header: PElement; implementation {$R *.dfm} constructor Queue.QueueCreate(Value:Integer); var Now:PElement; begin New(now); New(Header); Now^.FValue:=Value; Now^.FNext:=nil; Header:=nil; Header:=Now; // программа отрабатывает до сюда и вылетает end; procedure Queue.push(Value:Integer); var Now:PElement; begin New(now); Now^.FValue:=Value; Now^.FNext:=Header; Header:=Now; end; function Queue.pop():integer; var Now:PElement; begin New(Now); Now:=Header; while not(Now^.FNext^.FNext = nil) do Now:=Now^.FNext; result:=Now^.FNext^.FValue; dispose(Now^.FNext^.FNext); Now^.FNext:=nil; end; function Queue.GetValue():integer; var Now:PElement; begin New(Now); Now:=Header; while Now^.FNext = nil do Now:=Now^.FNext; result:=Now^.FValue; end; function Queue.IsEmpty():boolean; begin If Header=nil then result:=false else result:=true; end; procedure TForm1.Button1Click(Sender: TObject); begin; Queue1.QueueCreate(0); // ошибка при завершении операции Queue1.Push(9); end; end. Казалось бы, все компилится, значит, половина дела сделана. Но! Вылетает ошибка при создании очереди (пометил их в коде комментариями), ругается на кривой доступ к памяти. Ковыряюсь уже порядка недели по паре часов в день, никак не могу понять, где я не прав. З.Ы. Переменная Header в изначальном варианте вообще должна была быть полем у создаваемого класса. |
#2
|
||||
|
||||
реализация:
Код:
unit UnitQueue; interface type PElement = ^TElement; TElement = record Value: Integer; Parent: PElement; end; TQueue = class(TObject) private Top: PElement; public constructor Create; destructor Destroy; override; function GetValue: Integer; function IsEmpty: Boolean; function Pop: Integer; procedure Push(AValue: Integer); end; implementation constructor TQueue.Create; begin Top:=nil; end; destructor TQueue.Destroy; begin while not IsEmpty do Pop; inherited Destroy; end; function TQueue.GetValue: Integer; begin Result:=Top^.Value; end; function TQueue.IsEmpty: Boolean; begin Result:=Top=nil; end; function TQueue.Pop: Integer; var Now: PElement; begin Now:=Top; Result:=Now^.Value; Top:=Now^.Parent; Dispose(Now); end; procedure TQueue.Push(AValue: Integer); var Now: PElement; begin New(Now); Now^.Value:=AValue; Now^.Parent:=Top; Top:=Now; end; end. использование: Код:
FQueue: TQueue; begin FQueue:=TQueue.Create; FQueue.Push(0); FQueue.Push(100); FQueue.Push(255); ListBox1.Items.Add(IntToStr(FQueue.GetValue)); ListBox1.Items.Add(IntToStr(FQueue.GetValue)); ListBox1.Items.Add(IntToStr(FQueue.GetValue)); ListBox1.Items.Add(IntToStr(FQueue.Pop)); ListBox1.Items.Add(IntToStr(FQueue.Pop)); ListBox1.Items.Add(IntToStr(FQueue.Pop)); FQueue.Free; end; Пишу программы за еду. __________________ |
#3
|
|||
|
|||
Шикарно! Но, вот, несколько вопросов, дабы лучше понимать свои ошибки:
1. Для чего нужно обнуление Top'а в конструкторе? 2. Что делает inherited в деконструкторе? Не могу найти простого объяснения на русском языке. Просто чтобы удостовериться: здесь FILO-стек? Если да, то я, в принципе, с легкостью переделаю, огромное спасибо за помощь. |
#4
|
||||
|
||||
1. привычка ВСЕ инициализировать
2. т.к. переопредилили destructor (override), хочется вызвать метод предка 3. да Пишу программы за еду. __________________ |
#5
|
|||
|
|||
1. Если не обнулять, могут ли быть проблемы в работе, или это просто правила хорошего кодинга (раз уж доучиваюсь с быдлокодера, полезно бы мне и это знать)
2. Имею ввиду, что вообще делает данный оператор? Вызывает исходный метод предка прямиком из перегруженного, я правильно понял? Т.Е, в данном случае, он используется для того, чтобы дописать к исходному методу некую стороннюю часть? |