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
| program Project1;
{$APPTYPE CONSOLE}
uses
SysUtils, Windows;
type
//Основные данные.
TData = String;
//Указатель на элемент очереди.
TPElem = ^TElem;
//Элемент очереди.
TElem = record
Data : TData; //Основные данные.}
PNext : TPElem; //Указатель на следующий элемент очереди.
end;
//Очередь.
TQueue = record
PFirst, PLast : TPElem; //Указатели на первый и на последний элементы очереди.
end;
{Начальная инициализация очереди. Внимание! Эту процедуру можно выполнять
только в отношении пустой очереди. Иначе будут утечки памяти.
Если очередь непуста, то следует применить вызов QFree().}
procedure Init(var aQ : TQueue);
begin
aQ.PFirst := nil;
aQ.PLast := nil;
end;
//Добавление элемента в конец очереди.
procedure Push(var aQ : TQueue; const aData : TData);
var
PElem : TPElem;
begin
New(PElem);
PElem^.Data := aData;
PElem^.PNext := nil;
if aQ.PFirst = nil then
aQ.PFirst := PElem
else
aQ.PLast^.PNext := PElem;
aQ.PLast := PElem;
end;
{Изъятие элемента из начала очереди. Если очередь не пуста, то
из начала очереди извлекается элемент и его значение возвращается
через параметр aData. В этом случае функция возвращает True.
Если очередь пуста, то операция отменяется и функция возвращает False.}
function Pop(var aQ : TQueue; var aData : TData) : Boolean;
var
PElem : TPElem;
begin
Result := False;
if aQ.PFirst = nil then
Exit;
PElem := aQ.PFirst;
aData := PElem^.Data;
aQ.PFirst := PElem^.PNext;
if aQ.PFirst = nil then
Init(aQ);
Dispose(PElem);
Result := True;
end;
//Освобождение памяти, выделенной для элементов очереди (очистка очереди).
procedure QFree(var aQ : TQueue);
var
Data : TData;
begin
while Pop(aQ, Data) do;
end;
//Распечатка очереди в направлении: начало - конец.
procedure QWriteln(const aQ : TQueue);
var
PElem : TPElem;
i : Integer;
begin
PElem := aQ.PFirst;
if PElem = nil then
Writeln('Очередь пуста.')
else
begin
i := 0;
while PElem <> nil do
begin
Inc(i);
if i > 1 then
Write(', ');
Write(PElem^.Data);
PElem := PElem^.PNext; //Указатель на следующий элемент.
end;
Writeln;
end;
end;
const
M = 6;
var
Q1, Q2 : TQueue;
Data : TData;
i : Integer;
S : String;
begin
{Переключение окна консоли на кодовую страницу CP1251 (Win-1251).
Если после переключения русские буквы показываются неверно,
следует открыть системное меню консольного окна - щелчком мыши в левом
верхнем углу окна консоли и выбрать:
Свойства - закладка "Шрифт" - выбрать шрифт: "Lucida Console".}
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
//Начальная инициализация очередей.
Init(Q1);
Init(Q2);
repeat
//Добавление элементов в первую очередь.
for i := 1 to M do
Push(Q1, IntToStr(i));
Writeln('Составлена исходная очередь (начало - конец):');
QWriteln(Q1);
//Решение.
//Добавляем во вторую очередь строку = '0'.
Push(Q2, '0');
//Переливаем элементы из первой очереди - во вторую очередь.
while Pop(Q1, Data) do
Push(Q2, Data);
//Добавляем во вторую очередь строку = '0'.
Push(Q2, '0');
//Ответ.
Writeln('Составлена требуемая очередь (начало - конец):');
QWriteln(Q2);
//Освобождение памяти, выделенной для элементов очередей.
QFree(Q1);
QFree(Q2);
Writeln('Память, выделенная для очередей, освобождена.');
Writeln('Повторить - Enter, выход - любой символ + Enter.');
Readln(S);
until S <> '';
end. |