C.Ю.Соловьев

Методические материалы
по курсу
"Алгоритмы и алгоритмические языки"

Программа курса
Программирование в машинных кодах
Примеры-1
Примеры-2
Пример "большой" программы
Нисходящее программирование
Ссылочные типы
Структуры данных
Очереди и стеки
Деревья поиска
AVL-деревья
Таблицы
Хеш-таблицы
Динамические страницы

Очереди

(* Очередь - последовательность (однотипных) элементов данных, в которой:  *)
(* - включение элементов выполняется на одном конце последовательности; а  *)
(* - выбор элементов - на другом конце последовательности.                 *)
(* *)
(* Основные операции:
(* - включить в очередь новый элемент;         PushOh                      *)
(* - выбрать элемент из очереди;                PopOh                      *)
(* + породить пустую очередь;                  BornOh                      *)
(* + проверить наличие элементов в очереди.     EmpOh                      *)
(* Пример. Очередь символов.                                    *)
(*         Реализация в виде циклического массива Oh            *)
(*         Bg - позиция чтения из очереди                       *)
(*         Ko - количество элементов в очереди                  *)
 
program ExmOh;
 
Const   So = 8;                     (* So+1 - мах эл-тов в очереди *)
Var     Oh : array [0..So] of char;
     Bg,Ko : integer;
         A : char;
 
procedure PushOh(A : char);
   var L : integer;
begin   if Ko < So + 1  then begin
           L:=(Bg + Ko) mod (So + 1);
           Oh[L]:=A;
           Ko:=Ko+1
        end                      end;
 
procedure PopOh(var A : char);
begin   if 0 < Ko then begin
           A:=Oh[Bg];
           Ko:=Ko-1;
           Bg:=(Bg + 1) mod (So + 1);
        end                      end;
 
function EmpOh : boolean;
begin    EmpOh:=(Ko = 0)   end;
 
procedure BornOh;
begin   Bg:=0;
        Ko:=0    end;
 
begin   (* Пример внутри примера *)
        BornOh;
 
        PushOh(';'); PopOh(A);
        PushOh(';'); PopOh(A);
        PushOh(';'); PopOh(A);
        PushOh(';'); PopOh(A);
        PushOh(';'); PopOh(A);
 
writeln('Bg = ',Bg,'  Ko = ',Ko);  (* Bg = 5; Ko = 0 *)
        (* Посимвольный ввод 'Иванов' *)
        PushOh('И'); PushOh('в');PushOh('а');
        PushOh('н'); PushOh('о');PushOh('в');
writeln('Bg = ',Bg,'  Ko = ',Ko);  (* Bg = 5; Ko = 6; Oh = 'ов***Иван' *)
        PushOh('а');
writeln('Bg = ',Bg,'  Ko = ',Ko);  (* Bg = 5; Ko = 7; Oh = 'ова**Иван' *)
        PopOh(A);
writeln('Bg = ',Bg,'  Ko = ',Ko);  (* Bg = 6; Ko = 6; Oh = 'ова***ван' *)
writeln(' A = ',A);
        while not EmpOh do begin
           PopOh(A);
           write(A)
        end;
        writeln;
writeln('Bg = ',Bg,'  Ko = ',Ko);
        (* ... *)
end.
 
(* Протокол      Bg = 5  Ko = 0
                 Bg = 5  Ko = 6
                 Bg = 5  Ko = 7
                 Bg = 6  Ko = 6
                  A = И
                 ванова
                 Bg = 3  Ko = 0
Конец протокола *)

Стеки (Магазины)

(* Стек - последовательность (однотипных) элементов данных, в которой      *)
(* включение/выбор элементов выполняются на одном конце последовательности *)
(* *)
(* Основные операции:
(* - включить в стек новый элемент;            Push                        *)
(* - выбрать элемент из стека;                  Pop                        *)
(* + породить пустой стек;                     Born                        *)
(* + проверить наличие элементов в стеке.       Emp                        *)
 
(* Пример. Быстрая сортировка методом свечи целочисленного массива.        *)
(* Пусть   MACC = array [1..2200] of integer;                              *)
(*         K - количество элементов в массиве A : MACC                     *)
(* Рекурсивная реализация *)
 
procedure Rord(var A : MACC; K : integer);
    procedure MEH(L,R : integer);
        var Z : integer;
    begin   Z:=A[L];
               A[L]:=A[R];
                     A[R]:=Z
    end;
    function Candle(H,K : integer) : integer;
       label 777;
       var Hp,Kp,I,X : integer;
    begin   X:=A[H];            (* Представитель A[H..K] *)
            Hp:=H; Kp:=K;
      777:  while A[Hp] < X do Hp:=Hp+1;
            for I:=Kp downto Hp do
            if not(X <= A[I]) then begin
               Kp:=I;
               MEH(Hp,Kp);
               goto 777
            end;
            Candle:=Hp
    end;
    procedure RE(H,K : integer);
       var M : integer;
    begin   if K-H+1 <= 1 then else begin
               M:=Candle(H,K);
               if M = H then RE(H+1,K) else begin
                             RE(H,M-1);
                             RE(M,  K)
               end
            end
    end;
    begin RE(1,K)   end; (* of Rord *)
(* Реализация с помощью стека *)
 
procedure Uord(var A : MACC; K : integer);
   var   SK : array [1..200,1..2] of integer;
       H,SP : integer;
   procedure PUSH(H,K : integer);
   begin   SP:=SP+1;
           SK[SP,1]:=H;
           SK[SP,2]:=K       end;
   procedure POP(var H,K : integer);
   begin   H:=SK[SP,1];
           K:=SK[SP,2];
           SP:=SP-1             end;
   procedure MEH(L,R : integer);
      var Z : integer;
   begin   Z:=A[L];
              A[L]:=A[R];
                    A[R]:=Z
   end;
   function Candle(H,K : integer) : integer;
      label 777;
      var Hp,Kp,I,X : integer;
   begin   X:=A[H];            (* Представитель A[H..K] *)
           Hp:=H; Kp:=K;
     777:  while A[Hp] < X do Hp:=Hp+1;
           for I:=Kp downto Hp do
           if not(X <= A[I]) then begin
              Kp:=I;
              MEH(Hp,Kp);
              goto 777
           end;
           Candle:=Hp
   end;
   procedure Un(H,K : integer);
      var M : integer;
   begin   if K-H+1 <= 1 then else begin
              M:=Candle(H,K);
              if M = H then PUSH(H+1,K) else begin
                            PUSH(H,M-1);
                            PUSH(M,  K)
              end
           end
   end;
   begin   SP:=0;                (* Инициализация стека *)
           PUSH(1,K);            (* Исходная задача     *)
           while 0 < SP do begin (* Пока стек не пуст   *)
              POP(H,K);
               Un(H,K)
           end
   end;

Вопросы?