Форум программистов, компьютерный форум, киберфорум
Delphi для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.62/47: Рейтинг темы: голосов - 47, средняя оценка - 4.62
 Аватар для bretba
63 / 58 / 13
Регистрация: 24.07.2011
Сообщений: 343

Стек, Дек, Очередь — в чем различие и суть?

29.06.2012, 10:45. Показов 9012. Ответов 11
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Не могу разобраться в списках.Не понимаю как работать со списками.А точнее не могу отличить очередь,стек и дек.

На теории понимаю все))стек-последний элемент выходит первым,дек-первый элемент выходит первым,дек-есть "голова" и "хвост" в отличие от стека и очереди.

Теперь вопросы:
Как определить с каким мы видом списка работаем,если структура составления одна и та же-что у стека,что у дека,что у очереди:
Delphi
1
2
3
4
5
TPList=^TList;
TList=record
x:integer;
next:TPList;
end;
2.Можете проверить,правильный ли я код написал для создания списка/добавления элемента в список/вывод элемента

Стек:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
TPList=^TList;
TList=record
x:integer;
next:TPList;
end;
var
golova:TPList;
...
...
//добавление элемента
procedure addelem(var golova1:TPList;r:integer);
var
elem:TPList;
begin
new(elem);
elem^.x:=r;
elem^.next:=golova1;//что значит эта строчка?Типа переход на другой элемент это я знаю,но почему тогда не golova1:=elem^.next;
golova1:=elem;//что значит эта строчка?
end;
 
//процедура заполнения стека
//к примеру 1 3 5 1 9 я ввел.
procedure TForm1.Button1Click(Sender:TObject);
begin
addelem(golova,strtoint(edit1.text));
end;
 
//процедура вывода элемента списка
//если я ввел 1 3 5 1 9,то так как это стек,с помощью этой процедуры на экран выдаст мне 9 1 5 3 1(так как "последний пришел-первый вышел") Правильно?
procedure TForm1.Button2Click(Sender:TObject);
var
golova2:TPList;
begin
golova2:=golova;
while(golova2<>nil) do
begin
memo1.lines.add(inttostr(golova2^.x));
golova2:=golova2^.next; //а вот тут уже переход на элемент следующий другой какой -то.Не так,как было в процедуре добавления элемента elem^.next:=golova1;
end;
end;
Дек:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
TPList=^TList;
TList=record
x:integer;
next:TPList;
end;
var
golova,hvost:TPList;
...
...
//добавление элемента в начало(такое же как у стека)
procedure addfirst(var golova1:TPList;r:integer);
var
elem:TPList;
begin
new(elem);
elem^.x:=r;
elem^.next:=golova1;
тогда не golova1:=elem^.next;
golova1:=elem;
end;
 
//добавление элемента в конец
//НЕ ПОНИМАЮ НИ ОДНОЙ СТРОКИ!ПОМОГИТЕ РАЗОБРАТЬСЯ)
procedure addlast(var hvost1:TPList;r:integer);
begin
new(hvost1^.next);
hvost1^.next^.x:=r;
hvost1^.next^.next:=nil;
hvost1:=hvost1^.next;
end;
 
//процедура заполнения дека с начала и с конца
//к примеру 1 3 5 1 9 я ввел.
procedure TForm1.Button1Click(Sender:TObject);
begin
if radiogroup1.itemindex=0 then addfirst(golova,strtoint(edit1.text)) else addlast(hvost,strtoint(edit1.text));
end;
 
//вывод дека с конца и начала(по принципу очереди-пришел первый,вышел первый)
procedure TForm1.Button2Click(Sender:TObject);
var
golova2,hvost2:TPList;
begin
if radiogroup1.itemindex=0 then
begin
golova2:=golova;
while(golova2<>nil) do
begin
memo1.lines.add(inttostr(golova2^.x));
golova2:=golova2^.next;
end
else
begin//вот тут хочу выводить с конца элементы...но мне кажется не будет работать?
hvost2:=hvost;
while(hvost2<>nil) do
begin
memo1.lines.add(inttostr(hvost2^.x));
hvost2:=hvost2^.next;
end;
end;
end;
Очередь:
А как создать очередь и работать с ней вообще не знаю

Помогите пожалуйста!!

Добавлено через 9 часов 1 минуту
Ну так кто-нибудь поможет разобраться?завтра экзамен(
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
29.06.2012, 10:45
Ответы с готовыми решениями:

Стек, дек, очередь
Вообщем нужны примеры программ описание стек, дек и очереди.Есть одно нужны программы с интерфейсом. Помогите пожалуйста!

Стек, очередь, дек
. Напишите программу, которая «переворачивает» массив, записанный в файл, с помощью стека. Размер массива неизвестен. . Напишите...

Стек, очередь, дек - ИДЕЯ (реализация?)
Задание лабораторки: Хочу создать программу про Библиотеку (типа жизненный пример) Три groupBox'a: СТЕК - Сдача книг (как...

11
 Аватар для Одиночка
3944 / 1869 / 337
Регистрация: 16.03.2012
Сообщений: 3,880
29.06.2012, 11:03
Лучший ответ Сообщение было отмечено Памирыч как решение

Решение

Слишком много вопросов. Но попробую отвечать по порядку:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
//добавление элемента в начало списка...
procedure addelem(var golova1:TPList;r:integer);
var
  elem:TPList;
begin
  new(elem);
  elem^.x:=r;
  elem^.next:=golova1;
//Новый элемент теперь будет первым, первый старый - за ним. Поэтому устанавливается ссылка с
//нового первого на следующий, т.е. на старый первый
  golova1:=elem; //А теперь меняем сам указатель на головной элемент
end;
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//процедура вывода элемента списка
//если я ввел 1 3 5 1 9,то так как это стек,с помощью этой процедуры на экран выдаст
//мне 9 1 5 3 1(так как "последний пришел-первый вышел") Правильно?
//Если элементы вводились в том порядке, как перечислены - 
//каждый новый вставлялся в начало списка
//Если теперь перебирать с начала списка, так и получится - обратный порядок
procedure TForm1.Button2Click(Sender:TObject);
var
  golova2:TPList;
begin
  golova2:=golova; //Указатель на начало списка во временную переменную
  while(golova2<>nil) do //Ссылка с последнего элемента nil - ни куда не ведёт
  begin
     memo1.lines.add(inttostr(golova2^.x));
     golova2:=golova2^.next; //в предыдущей процедуре менялся головной элемент. Здесь тоже меняется указатель, но на следующий элемент. Сама переменная golova2 - временная - она не меняет сам список, а просто поочерёдно ссылается на все элементы списка
  end;
end;
Дэк:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
//добавление элемента в конец
//НЕ ПОНИМАЮ НИ ОДНОЙ СТРОКИ!ПОМОГИТЕ РАЗОБРАТЬСЯ)
procedure addlast(var hvost1:TPList;r:integer);
begin
//Ссылка с последнего элемента на следующий - пустая - дальше списка нет
//поэтому можно сразу создавать на нём новый элемент (New - создаёт новый указатель)
//можно было это сделать через промежуточную переменную, а потом присвоить её hvost1^.next
new(hvost1^.next);
hvost1^.next^.x:=r; //Это уже работаем с новым указателем
hvost1^.next^.next:=nil; //Замыкаем ссылку нового (последнего) указателя - пустая ссылка
hvost1:=hvost1^.next; //hvost1^.next теперь ссылается на новый указатель - делаем чтобы hvost1 - указывал на него
end;
Вот немного изменённый код последней процедуры, может понятней будет:
Delphi
1
2
3
4
5
6
7
8
9
10
procedure addlast(var hvost1:TPList;r:integer);
Var
  temp:TPList;
begin
  new(temp);
  temp^.x:=r; 
  temp^.next:=nil;
  hvost1^.next:=temp;
  hvost1:=temp;
end;
begin//вот тут хочу выводить с конца элементы...но мне кажется не будет работать?
Да, работать не будет, потому что нет ссылок на предыдущие элементы, только на следующие. Для того, чтобы можно было с конца в начало обрабатывать эту цепочку нужно кроме next добавить туда ещё ссылки prev и определять их тоже при изменении списка.
Я думаю, в случае Дєк-а смысл в том, что ты вставляешь новые элементы в конец списка, а выводишь их с начала. Тогда первый вошел - первый вышел.

Кстати. Почитал Википедию и оказывается, то, что ты назвал Дэк - это как раз очередь. И там элементы добавляются с конца, а выбираются с начала. А Дэк - это двухсвязный список. И его обработка следующая:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
Type
TPList=^TList;
TList=record
  x:integer;
  next:TPList;
  prev:TPList;
end;
 
Var
  Golova : TPList = Nil;
  Hvost : TPList = Nil;
  t : TPList; //Для промежуточного использования
 
//Добавление элемента в начало...
Procedure AddNewBegList(Var Golova,Hvost:TPList; r:Integer);
Var
  t : TPList;
Begin
  New(t);
  t^.x:=r;
  t^.next:=Golova;
  t^.prev:=Nil;
  If Golova<>Nil Then Golova^.prev:=t Else Hvost:=t;
  Golova:=t;
End;
 
//Добавление элемента в конец...
Procedure AddNewEndList(Var Golova,Hvost:TPList; r:Integer);
Var
  t : TPList;
Begin
  New(t);
  t^.x:=r;
  t^.next:=Nil;
  t^.prev:=Hvost;
  If Hvost<>Nil Then 
  Hvost^.next:=t Else Golova:=t;
  Hvost:=t;
End;
 
//Удаление элемента из начала...
Procedure DelBegList(Var Golova,Hvost:TPList);
Var
  t : TPList;
Begin
  If Golova=Nil Then Exit;
  t:=Golova;
  Golova:=Golova^.next;
  If Golova<>Nil Then Golova^.prev:=Nil Else Hvost:=Nil;
  Dispose(t);
End;
 
//Удаление элемента из конца...
Procedure DelEndList(Var Golova,Hvost:TPList);
Var
  t : TPList;
Begin
  If Hvost=Nil Then Exit;
  t:=Hvost;
  Hvost:=Hvost^.prev;
  If Hvost<>Nil Then Hvost^.next:=Nil Else Golova:=Nil;
  Dispose(t);
End;
 
 
  //Просмотр с начала...
  t:=Golova;
  While t<>Nil Do
  Begin
    Memo1.Lines.Add(IntToStr(t^.x));
    t:=t^.next;
  End;
 
  //Просмотр с конца...
  t:=Hvost;
  While t<>Nil Do
  Begin
    Memo1.Lines.Add(IntToStr(t^.x));
    t:=t^.prev;
  End;
 
  //Освобождение памяти...
  t:=Golova;
  While t<>Nil Do
  Begin
    Golova:=Golova^.next;
    Dispose(t);
    t:=Golova;
  End;
  Golova:=Nil;
  Hvost:=Nil;
Я мог где-то ошибиться, поэтому советую поискать на форуме "Двухсвязные списки".
1
 Аватар для bretba
63 / 58 / 13
Регистрация: 24.07.2011
Сообщений: 343
29.06.2012, 13:38  [ТС]
Более менее понятно))спасибо))

Еще возникли некоторые вопросы:
1.Можно ли не только с конца или начала заполнять список?К примеру в середине добавить элемент,или массив элементов...или к примеру после какого-то элемента добавить что-то....Можно ли и как такое организовать?
2.Значит я понял что Очередь=Дек да?Тоесть если по задаче сказано мне-"создать две очереди..." это значит создать два Дека да?
0
 Аватар для Одиночка
3944 / 1869 / 337
Регистрация: 16.03.2012
Сообщений: 3,880
29.06.2012, 13:47
Значит я понял что Очередь=Дек
Нет. То, что ты называл Дэк - на самом деле это очередь. А для настоящего Дэк-а (дввунаправленного списка) я привёл тебе набор процедур.
В очередь ты добавляешь данные в конец, а выбираешь с начала.
Вообще я Вику читал.
Добавлять, конечно, можно и в средину списка. Найти нужный элемент после (или перед) которого вставлять делаешь ссылки на него, а с него на соседние и всё.
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
 Аватар для volvo
33414 / 21523 / 8237
Регистрация: 22.10.2011
Сообщений: 36,923
Записей в блоге: 12
29.06.2012, 13:49
Цитата Сообщение от Одиночка Посмотреть сообщение
Кстати. Почитал Википедию и оказывается, то, что ты назвал Дэк - это как раз очередь. И там элементы добавляются с конца, а выбираются с начала.
Это неправда. DEQue = Double Ended Queue (двусторонняя очередь), то есть, смысл - в том, что в него можно (в отличие от очереди) добавлять данные с двух сторон. И изымать - тоже с двух сторон.
0
 Аватар для Одиночка
3944 / 1869 / 337
Регистрация: 16.03.2012
Сообщений: 3,880
29.06.2012, 13:57
Для двусвязного списка
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
//Добавление элемента в средину...
//После элемента AfterEl
Procedure AddNewBegList(Var ,Hvost,AfterEl:TPList; r:Integer);
Var
  t : TPList;
Begin
  New(t);
  t^.x:=r;
  
  t^.next:=AfterEl^.next;
  AfterEl^.next:=t;
  If t^.next<>Nil Then t^.next^.prev:=t //Ссылка со следующего на новый
  else Hvost:=t; //Новый стал последним
End;
Добавлено через 3 минуты
UI: Ты бы сначала прочитал о чём я говорил. А то сразу - неправда.
В его первом посте Дэк-ом он называл как раз очередь. Я об этом ему и говорил.
0
 Аватар для bretba
63 / 58 / 13
Регистрация: 24.07.2011
Сообщений: 343
29.06.2012, 14:40  [ТС]
Блин,я не понимаю Вас,ребят!

Можете просто привести пример-Создание очереди и вывод ее и все)я так пойму лучше))может что еще спрошу по коду

если не сложно))
0
 Аватар для Mawrat
13116 / 5897 / 1708
Регистрация: 19.09.2009
Сообщений: 8,809
29.06.2012, 14:55
Лучший ответ Сообщение было отмечено Памирыч как решение

Решение

Предложу пример со стеком и очередью. На форму надо положить TButton и TMemo.
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
type
  //Указатель на элемент списка (это элемент очереди или стека).
  TPElem = ^TElem;
  //Элемент списка.
  TElem = record
    Data : Integer; //Основные данные.
    PNext : TPElem; //Указатель на следующий элемент списка.
  end;
  //Очередь.
  TQueue = record
    PFirst, PLast : TPElem; //Указатели на первый и на последний элемент очереди.
  end;
  //Для стека отдельный тип можно не создавать. Стек будет представлен в виде
  //указателя на элемент, расположенный на вершине стека. Поэтому, переменная,
  //представляющая стек, будет иметь тип TPElem.
 
//Стек. Процедуры.
 
//Инициализация стека. Внимание! Эту процедуру можно выполнять только в том
//случае, если стек пуст. Иначе, произойдут утечки памяти.
//Эту процедуру следует выполнять только для начальной инициализации стека.
procedure StackInit(var aSt : TPElem);
begin
  aSt := nil;
end;
 
//Добавление элемента на вершину стека.
procedure StackPush(var aPStack, aPElem : TPElem);
begin
  if aPElem = nil then Exit;
  aPElem^.PNext := aPStack;
  aPStack := aPElem;
end;
 
//Изъятие элемента с вершины стека.
//Если стек не пуст, то с вершины стека изымается элемент и возвращается
//через параметр aPElem. В этом случае, функция возвращает значение True.
//Если стек пуст, то операция отменяется, а функция возвращает значение False.
function StackPop(var aPStack, aPElem : TPElem) : Boolean;
begin
  Result := False;
  if aPStack = nil then Exit;
  aPElem := aPStack;
  aPStack := aPElem^.PNext;
  Result := True;
end;
 
//Удаление стека из памяти (очистка стека).
procedure StackFree(var aPStack : TPElem);
var
  PElem : TPElem;
begin
  while StackPop(aPStack, PElem) do Dispose(PElem);
end;
 
//Распечатка стека.
function StackToStr(var aPStack : TPElem) : String;
var
  PSt, PElem : TPElem;
begin
  if aPStack = nil then begin
    Result := 'Стек пуст.';
    Exit;
  end;
  Result := '';
 
  //Начальная инициализация вспомогательного стека.
  PSt := nil;
  //Переливаем все элементы стека aPStack в стек PSt и выполняем распечатку.
  while StackPop(aPStack, PElem) do begin
    StackPush(PSt, PElem);
    if Result <> '' then Result := Result + ', ';
    Result := Result + IntToStr(PElem^.Data);
  end;
  //Возвращаем элементы из стека PSt в стек aPStack. При этом, элементы
  //в стеке aPStack окажутся в том же порядке, в каком они были до распечатки.
  while StackPop(PSt, PElem) do StackPush(aPStack, PElem);
end;
 
//Очередь. Процедуры.
 
//Инициализация очереди. Внимание! Эту процедуру можно выполнять только в том
//случае, если очередь пуста. Иначе, произойдут утечки памяти.
//Эту процедуру следует выполнять только для начальной инициализации очереди.
procedure QueueInit(var aQueue : TQueue);
begin
  aQueue.PFirst := nil;
  aQueue.PLast := nil;
end;
 
//Добавление элемента в конец очереди.
procedure QueuePush(var aQueue : TQueue; var aPElem : TPElem);
begin
  if aPElem = nil then Exit;
 
  aPElem^.PNext := nil;
  if aQueue.PFirst = nil then
    aQueue.PFirst := aPElem
  else
    aQueue.PLast^.PNext := aPElem
  ;
  aQueue.PLast := aPElem;
end;
 
//Изъятие элемента из начала очереди.
//Если очередь не пуста, то из её начала изымается элемент и возвращается
//через параметр aPElem. В этом случае, функция возвращает значение True.
//Если очередь пуста, то операция отменяется, а функция возвращает значение False.
function QueuePop(var aQueue : TQueue; var aPElem : TPElem) : Boolean;
begin
  Result := False;
  if aQueue.PFirst = nil then Exit;
 
  aPElem := aQueue.PFirst;
  aQueue.PFirst := aPElem^.PNext;
  if aQueue.PFirst = nil then aQueue.PLast := nil;
  Result := True;
end;
 
//Удаление очереди из памяти (очистка очереди).
procedure QueueFree(var aQueue : TQueue);
var
  PDel : TPElem;
begin
  while QueuePop(aQueue, PDel) do Dispose(PDel);
end;
 
//Распечатка очереди.
function QueueToStr(var aQueue : TQueue) : String;
var
  QTmp : TQueue;
  PElem : TPElem;
begin
  if aQueue.PFirst = nil then begin
    Result := 'Очередь пуста.';
    Exit;
  end;
  Result := '';
 
  //Инициализация вспомогательной очереди.
  QueueInit(QTmp);
  //Переливаем элементы из исходной очереди во временную и при этом
  //выполняем распечатку.
  while QueuePop(aQueue, PElem) do begin
    QueuePush(QTmp, PElem);
    if Result <> '' then Result := Result + ', ';
    Result := Result + IntToStr(PElem^.Data);
  end;
  
  aQueue := QTmp;
end;
 
procedure TForm1.Button1Click(Sender: TObject);
const
  M = 20;
var
  PSt1, PSt2 : TPElem;
  Q : TQueue;
  PElem : TPElem;
  i : Integer;
begin
  //Начальная инициализция стеков.
  StackInit(PSt1);
  StackInit(PSt2);
  //Начальная инициализация очереди.
  QueueInit(Q);
 
  //Заполянем очередь.
  Randomize;
  for i := 1 to Random(M) do begin
    New(PElem);
    PElem^.Data := i;
    QueuePush(Q, PElem);
  end;
  Memo1.Lines.Add('--------------------------------------------------');
  Memo1.Lines.Add('Очередь (начало - конец):');
  Memo1.Lines.Add( QueueToStr(Q) );
 
  //Переливаем элементы из очереди в первый стек.
  while QueuePop(Q, PElem) do StackPush(PSt1, PElem);
  Memo1.Lines.Add('----------');
  Memo1.Lines.Add('Переливаение элементов из очереди в первый стек.');
  Memo1.Lines.Add('Первый стек (вершина - дно):');
  Memo1.Lines.Add( StackToStr(PSt1) );
 
  //Переливаем элементы из первого стека во второй стек.
  while StackPop(PSt1, PElem) do StackPush(PSt2, PElem);
  Memo1.Lines.Add('----------');
  Memo1.Lines.Add('Переливаение элементов из первого стека во второй стек.');
  Memo1.Lines.Add('Второй стек (вершина - дно):');
  Memo1.Lines.Add( StackToStr(PSt2) );
 
  //Удаляем стеки и очереди из памяти.
  StackFree(PSt1);
  StackFree(PSt2);
  QueueFree(Q);
  Memo1.Lines.Add('----------');
  Memo1.Lines.Add('Стеки и очереди удалены из памяти. Работа завершена.');
end;
2
 Аватар для bretba
63 / 58 / 13
Регистрация: 24.07.2011
Сообщений: 343
29.06.2012, 17:36  [ТС]
Все равно тяжело понимается именно про очередьЗавтра экзамен...не знаю,что делать

Вот написал небольшую программу по созданию Стека/Дека/(Очереди),Добавлению элемента в данные виды списков,Удаление данных списков и вывод элементов списков на экран.

*Очередь взял в скобки,потому что все сделал кроме нее))Помогите организовать,я закоментил где нужно))

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls;
 
type
  TForm1 = class(TForm)
    RadioGroup1: TRadioGroup;
    Edit1: TEdit;
    Label1: TLabel;
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    RadioGroup2: TRadioGroup;
    Label2: TLabel;
    memo1: TMemo;
    procedure RadioGroup1Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure Edit1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
Type
TPList=^TList;
TList=record
x:integer;
next:TPList;
end;
 
var
Stek:TPList;
HeadDek,TailDek:TPList;
var
  Form1: TForm1;
 
implementation
 
{$R *.dfm}
//процедура выбора вида списка,с которым будем работать
procedure TForm1.RadioGroup1Click(Sender: TObject);
begin
case radiogroup1.ItemIndex of
0:begin label1.Caption:='Введите элемент в Стек:'; radiogroup2.Enabled:=false; end;
1:begin label1.Caption:='Введите элемент в Дек:';radiogroup2.Enabled:=true; end;
2:begin label1.Caption:='Введите элемент в Очередь:'; radiogroup2.Enabled:=false; end;
end;
end;
 
//процедура заполнения списка
procedure TForm1.Button1Click(Sender: TObject);
var
elem:TPList;
begin
case radiogroup1.ItemIndex of
//заполнение стека
0:      begin
new(elem);
elem^.x:=strtoint(edit1.Text);
elem^.next:=Stek;
Stek:=elem;
        end;
//заполнения дека
1:      begin
//создание первого элемента,если список пуст
if (HeadDek=nil) then begin new(HeadDek);TailDek:=HeadDek;HeadDek^.x:=strtoint(edit1.Text);HeadDek^.next:=nil; end else
begin
case radiogroup2.ItemIndex of
//в начало
0:begin
new(elem);
elem^.x:=strtoint(edit1.Text);
elem^.next:=HeadDek;
HeadDek:=elem;
  end;
//в конец
1:begin
new(TailDek^.next);
TailDek^.next^.x:=strtoint(edit1.text);
TailDek^.next^.next:=nil;
TailDek:=TailDek^.next;
  end;
end;
end;
        end;
//заполнение очереди
2:      begin
//ТУТ НУЖНО ЗАПОЛНИТЬ ОЧЕРЕДЬ
        end;
end;
end;
 
//процедура вывода списка
procedure TForm1.Button2Click(Sender: TObject);
var
Stek1:TPList;
HeadDek1,TailDek1:TPList;
begin
memo1.Clear;
case radiogroup1.ItemIndex of
//вывод стека
0:      begin
if Stek=nil then memo1.Lines.add('Стек пуст!');
Stek1:=Stek;
while (Stek1<>nil) do
 begin
   memo1.Lines.Add(inttostr(Stek1^.x));
   Stek1:=Stek1^.next;
 end;
        end;
//вывод дека
1:      begin
if HeadDek=nil then  memo1.Lines.Add('Дек пуст!');
HeadDek1:=HeadDek;
while (HeadDek1<>nil) do
  begin
   memo1.Lines.Add(inttostr(HeadDek1^.x));
   HeadDek1:=HeadDek1^.next;
  end;
         end;
//вывод очереди
2:       begin
//ТУТ НУЖНО ВЫВОДИТЬ ОЧЕРЕДЬ
          end;
end;
end;
 
//процедура удаления списка
procedure TForm1.Button3Click(Sender: TObject);
var
elem:TPList;
begin
memo1.Clear;
case radiogroup1.ItemIndex of
//удаление стека
0:    begin
elem:=Stek;
while (elem<>nil) do
  begin
   Stek:=Stek^.next;
   Dispose(elem);
   elem:=Stek;
  end;
memo1.Lines.Add('Стек удален!');
       end;
//удаление дека
1:     begin
elem:=HeadDek;
while (elem<>nil) do
  begin
   HeadDek:=HeadDek^.next;
   Dispose(elem);
   elem:=HeadDek;
  end;
TailDek:=nil;
memo1.Lines.Add('Дек удален!');
        end;
//удаление очереди
2:      begin
//ТУТ НУЖНО УДАЛИТЬ ОЧЕРЕДЬ ИЗ ПАМЯТИ
         end;
end;
end;
 
procedure TForm1.Edit1Click(Sender: TObject);
begin
button1.Enabled:=true;
end;
 
end.
0
 Аватар для Одиночка
3944 / 1869 / 337
Регистрация: 16.03.2012
Сообщений: 3,880
29.06.2012, 20:43
Лучший ответ Сообщение было отмечено Памирыч как решение

Решение

Вот немного подправил. Добавь обработчики событий FormCreate и FormClose. А вообще почти всё правильно за исключением того, что я тебе объяснял, что такое Дэк, но ты так и не понял.
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls;
 
 
type
  TForm1 = class(TForm)
    RadioGroup1: TRadioGroup;
    Edit1: TEdit;
    Label1: TLabel;
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    RadioGroup2: TRadioGroup;
    Label2: TLabel;
    memo1: TMemo;
    procedure RadioGroup1Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure Edit1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
Type
  TPList=^TList;
  TList=record
    x:integer;
    next:TPList;
  End;
 
  TPDek=^TDek;
  TDek=record
    x:integer;
    prev:TPDek;
    next:TPDek;
  end;
 
var
  Form1: TForm1;
 
  Stek:TPList;
  HeadDek,TailDek:TPDek;
  HeadTurn,TailTurn:TPList;
 
implementation
 
{$R *.dfm}
 
//процедура выбора вида списка,с которым будем работать
procedure TForm1.RadioGroup1Click(Sender: TObject);
begin
  case radiogroup1.ItemIndex of
  0: begin label1.Caption:='Введите элемент в Стек:'; radiogroup2.Enabled:=false; end;
  1: begin label1.Caption:='Введите элемент в Дек:'; radiogroup2.Enabled:=true; end;
  2: begin label1.Caption:='Введите элемент в Очередь:'; radiogroup2.Enabled:=false; end;
  end;
end;
 
//процедура заполнения списка
procedure TForm1.Button1Click(Sender: TObject);
var
  elem:TPList;
  elemDek:TPDek;
begin
  case radiogroup1.ItemIndex of
  //заполнение стека
  0: begin
       new(elem);
       elem^.x:=strtoint(edit1.Text);
       elem^.next:=Stek;
       Stek:=elem;
     end;
  //заполнения дека
  1: begin
       //создание первого элемента,если список пуст
       if (HeadDek=nil) then
       begin
         new(HeadDek);
         TailDek:=HeadDek;
         HeadDek^.x:=strtoint(edit1.Text);
         HeadDek^.next:=nil;
         HeadDek^.prev:=nil;
       end else
       begin
         If radiogroup2.ItemIndex=0 Then
         //в начало
         begin
           new(elemDek);
           elemDek^.x:=strtoint(edit1.Text);
           elemDek^.next:=HeadDek;
           elemDek^.prev:=nil;
           HeadDek^.prev:=elemDek;
           HeadDek:=elemDek;
         end Else
         //в конец
         begin
           new(TailDek^.next);
           TailDek^.next^.x:=strtoint(edit1.text);
           TailDek^.next^.next:=nil;
           TailDek^.next^.prev:=TailDek;
           TailDek:=TailDek^.next;
         end;
       end;
     end;
  //заполнение очереди
  2: begin
       //создание первого элемента,если список пуст
       if (HeadTurn=nil) then
       begin
         new(HeadTurn);
         TailTurn:=HeadTurn;
         HeadTurn^.x:=strtoint(edit1.Text);
         HeadTurn^.next:=nil;
       end else
       begin
         //в конец списка
         new(TailTurn^.next);
         TailTurn^.next^.x:=strtoint(edit1.text);
         TailTurn^.next^.next:=nil;
         TailTurn:=TailTurn^.next;
       end;
     end;
  end;
end;
 
//процедура вывода списка
procedure TForm1.Button2Click(Sender: TObject);
var
  Stek1:TPList;
  HeadDek1:TPDek;
begin
  memo1.Clear;
  case radiogroup1.ItemIndex of
  //вывод стека
  0: begin
       if Stek=nil then memo1.Lines.add('Стек пуст!');
       Stek1:=Stek;
       while (Stek1<>nil) do
       begin
         memo1.Lines.Add(inttostr(Stek1^.x));
         Stek1:=Stek1^.next;
       end;
     end;
  //вывод дека
  1: begin
       if HeadDek=nil then  memo1.Lines.Add('Дек пуст!');
       HeadDek1:=HeadDek;
       while (HeadDek1<>nil) do
       begin
         memo1.Lines.Add(inttostr(HeadDek1^.x));
         HeadDek1:=HeadDek1^.next;
       end;
     end;
  //вывод очереди
  2: begin
       if HeadTurn=nil then memo1.Lines.add('Очередь пуста!');
       Stek1:=HeadTurn;
       while (Stek1<>nil) do
       begin
         memo1.Lines.Add(inttostr(Stek1^.x));
         Stek1:=Stek1^.next;
       end;
     end;
  end;
end;
 
//процедура удаления списка
procedure TForm1.Button3Click(Sender: TObject);
var
  elem:TPList;
  elemDek:TPDek;
begin
  memo1.Clear;
  case radiogroup1.ItemIndex of
  //удаление стека
  0: begin
       elem:=Stek;
       while (elem<>nil) do
       begin
         Stek:=Stek^.next;
         Dispose(elem);
         elem:=Stek;
       end;
       memo1.Lines.Add('Стек удален!');
     end;
  //удаление дека
  1: begin
       elemDek:=HeadDek;
       while (elemDek<>nil) do
       begin
         HeadDek:=HeadDek^.next;
         Dispose(elemDek);
         elemDek:=HeadDek;
       end;
       TailDek:=nil;
       memo1.Lines.Add('Дек удален!');
     end;
  //удаление очереди
  2: begin
       elem:=HeadTurn;
       while (elem<>nil) do
       begin
         HeadTurn:=HeadTurn^.next;
         Dispose(elem);
         elem:=HeadTurn;
       end;
       memo1.Lines.Add('Очередь удалена!');
     end;
  end;
 
end;
 
procedure TForm1.Edit1Click(Sender: TObject);
begin
  button1.Enabled:=true;
end;
 
procedure TForm1.FormCreate(Sender: TObject);
begin
  //Инициализация списков...
  Stek:=nil;
  HeadDek:=nil;
  TailDek:=nil;
  HeadTurn:=nil;
  TailTurn:=nil;
end;
 
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
var
  elem:TPList;
  elemDek:TPDek;
begin
  //Освободить память списков если забыли...
 
  //удаление стека
  elem:=Stek;
  while (elem<>nil) do
  begin
    Stek:=Stek^.next;
    Dispose(elem);
    elem:=Stek;
  end;
 
  //удаление дека
  elemDek:=HeadDek;
  while (elemDek<>nil) do
  begin
    HeadDek:=HeadDek^.next;
    Dispose(elemDek);
    elemDek:=HeadDek;
  end;
  TailDek:=nil;
 
  //удаление очереди
  elem:=HeadTurn;
  while (elem<>nil) do
  begin
    HeadTurn:=HeadTurn^.next;
    Dispose(elem);
    elem:=HeadTurn;
  end;
end;
 
end.
1
 Аватар для bretba
63 / 58 / 13
Регистрация: 24.07.2011
Сообщений: 343
30.06.2012, 00:28  [ТС]
Спасибо огромное!!!Все понял!

Но все же есть еще вопросик маленький...можешь если не сложно еще раз объяснить что такое prev и для чего он в Деке..если не сложно))
0
 Аватар для Одиночка
3944 / 1869 / 337
Регистрация: 16.03.2012
Сообщений: 3,880
30.06.2012, 00:41
Ты бы нашел в Википедии и почитал. Или хотя бы наши посты. DEQ - это ДВУНАПРАВЛЕННЫЙ список. Т.е. по нему можно ходить в обоих направлениях. Для этого есть prev - ссылка на предыдущий элемент. Т.е. Дэк можно выдавать и с конца. А очередь или стек - только с начала. Ну очередь - это, по сути, тот же стек. Но потому она и очередь, что в неё добавляют сзади, а выбирают спереди.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
30.06.2012, 00:41
Помогаю со студенческими работами здесь

В чем суть и различие NPAPI и PPAPI
Объясните, кто в теме, что это такое и с чем едят.

Каким образом можно записать стек и очередь в дек
Прошу помощи. Есть программа создания стека и очереди с динамическим распределением памяти. Каким образом их можно записать в дек?Заранее...

В чем состоит суть различие между операторами?
Начну вот с этих операторов ExitProcess(0); Applicaion.Terminate; halt(0);

Как можно объединить в одну структуру стек (очередь) и дек, при этом не создавая 2 структуры?
Доброго всем вечера! У меня возник вопрос такой)) Как я могу объединить в одну структуру стек(очередь) и дек, при это не создавая 2...

Реализовать пользовательские классы - дек, стек (LIFO), очередь (FIFO) на базе класса list библиотеки STL
Создать пользовательские классы - дек, стек (LIFO), очередь (FIFO) на базе класса list библиотеки STL. Написать тестирующую программу,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Новые блоги и статьи
Мысли в слух. Про "навсегда".
kumehtar 16.04.2026
Подумалось тут, что наверное очень глупо использовать во всяких своих установках понятие "навсегда". Это очень сильное понятие, и я только начинаю понимать край его смысла, не смотря на то что давно. . .
My Business CRM
MaGz GoLd 16.04.2026
Всем привет, недавно возникла потребность создать CRM, для личных нужд. Собственно программа предоставляет из себя базу данных клиентов, в которой можно фиксировать звонки, стадии сделки, а также. . .
Знаешь почему 90% людей редко бывают счастливыми?
kumehtar 14.04.2026
Потому что они ждут. Ждут выходных, ждут отпуска, ждут удачного момента. . . а удачный момент так и не приходит.
Фиксация колонок в отчете СКД
Maks 14.04.2026
Фиксация колонок в СКД отчета типа Таблица. Задача: зафиксировать три левых колонки в отчете. Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка) / / . . .
Настройки VS Code
Loafer 13.04.2026
{ "cmake. configureOnOpen": false, "diffEditor. ignoreTrimWhitespace": true, "editor. guides. bracketPairs": "active", "extensions. ignoreRecommendations": true, . . .
Оптимизация кода на разграничение прав доступа к элементам формы
Maks 13.04.2026
Алгоритм из решения ниже реализован на нетиповом документе, разработанного в конфигурации КА2. Задачи, как таковой, поставлено не было, проделанное ниже исключительно моя инициатива. Было так:. . .
Контроль заполнения и очистка дат в зависимости от значения перечислений
Maks 12.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: реализовать контроль корректности заполнения дат назначения. . .
Архитектура слоя интернета для сервера-слоя.
Hrethgir 11.04.2026
В продолжение https:/ / www. cyberforum. ru/ blogs/ 223907/ 10860. html Знаешь что я подумал? Раз мы все источники пишем в голове ветки, то ничего не мешает добавить в голову такой источник, который сам. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru