
- •Утверждаю Зам.Директора по учебной работе
- •Основы Алгоритмизации и программирования учебно-методическое пособие
- •220301 Автоматизированные системы обработки информации и правления
- •Введение
- •Основные этапы решения задач на эвм
- •Глава 1 способы записи алгоритма
- •1.1 Алгоритм и его свойства
- •Схемы алгоритма
- •1.2 Структуры алгоритмов
- •1.2.1 Алгоритм линейной структуры
- •1.2.2 Алгоритм разветвляющейся структуры
- •1.2.3 Алгоритм циклической структуры
- •1.2.4 Алгоритм со структурой итерационных циклов
- •1.2.5 Алгоритм со структурой вложенных циклов
- •Глава 2 программа на языке высокого уровня
- •2.1 Системы программирования
- •2.2 Характеристика языка программирования Паскаль
- •2.3 Алфавит и структура программы на Паскале Алфавит программы
- •Структура программы
- •Глава 3 Стандартные типы данных
- •3.1 Данные. Типы
- •3.2 Вещественные типы
- •3.3 Целочисленные типы
- •3.4 Символьный тип
- •3.5 Логический тип
- •4 Представление основных структур программирования: итерация, ветвление, повторение
- •4.1 Линейная структура (следование)
- •Var X,y,f: real;
- •4.2 Разветвляющая структура (ветвление)
- •4.3 Циклическая структура (повторение)
- •4.3.1 Оператор цикла с параметром
- •I : Integrer; {номер числа }
- •4.3.2 Оператор цикла с постусловием
- •I,n: integer;
- •4.3.3 Оператор цикла с предусловием
- •4.3.4 Итерационные циклы
- •Var r,a:real;
- •Приближенное вычисление функций
- •Решение уравнений приближенными методами
- •Метод деления отрезка пополам
- •Xsl, Xpr, a, b, e, y1, y2, Lev, Prav, y: Real;
- •Метод Ньютона
- •Метод прохождения отрезка с переменным шагом
- •Вычисление определенных интегралов
- •1. Метод прямоугольников
- •X: Real;
- •2. Метод трапеций
- •X: Real;
- •Глава 5 Типы данных, определяемые пользователем
- •5.1 Пользовательский тип данных
- •5.1.1 Типизированные константы
- •5.1.2 Перечисляемый тип
- •I:1..6; loto: num;
- •5.2 Массивы
- •I : integer;
- •5.2.1. Работа с одномерными массивами
- •I,sum : integer;
- •Var a: array [1..N] of real;
- •Var I,s,r: integer;
- •I : list;
- •I : integer;
- •X : mass;
- •I, j, p, n, m, k:integer;
- •I, j, k, nd : integer;
- •Xmin : real;
- •X : mass;
- •Var I, j, nd : integer;
- •X : mass;
- •5.2.2 Работа с двумерными массивами( матицы)
- •Var I,j,n : integer;
- •I,j,n,m : integer;
- •5.2.3 Сортировка массивов
- •Сортировка методом "пузырька"
- •X : Array [1..Nmax] Of Real;
- •X : Array [1..Nmax] Of Real;
- •Сортировка выбором
- •Обменная сортировка
- •Var m:array[1..1000] of integer;
- •I,z,n:integer; Key:byte;
- •Сортировка слиянием
- •Var { Описание массивов и переменных}
- •X, y: array[1..1000] of integer;
- •5.3 Строковые типы
- •Var s: string[10];
- •5.3.1 Операции над строками
- •5.3.2 Стандартные процедуры и функции для строк
- •Функция Length
- •Функция Upcase
- •Функция Copy
- •Функция Роs
- •I, n, p: integer;
- •I: integer;
- •I: integer;
- •Insert (word2, text, I);
- •Insert (chr (k-32), t, I);
- •Insert (chr (k-80), t, I);
- •Insert (‘е’, t, I);
- •Глава 6 Процедуры и функции
- •6.1 Процедуры
- •I : Integer;
- •I, n: integer;
- •Input _ mas (k, n);
- •I,n : Integer;
- •I,k : Integer;
- •6.2 Функции
- •I:Integer;
- •2) Массивы;
- •I,n : Integer;
- •I : Integer;
- •I,tn,tk:Real;
- •Глава 7 Программирование рекурсивных алгоритмов
- •7.1 Понятие рекурсии
- •7.2 Техника построения рекурсивных алгоритмов
- •7.3 Формы рекурсий
- •If Prim(I) then
- •7.4 Рекурсия и итерация
- •7.5 Программирование с использованием рекурсии
- •Var p: Integer;
- •Var X, y: Integer; begin
- •Var z: Real; begin
- •Var I:integer; j:real;
- •Глава 8 Файлы
- •8.1 Текстовые файлы
- •I,n : Integer; {Вспомогательные переменные}
- •8.2 Типизированные файлы
- •X,m,s : Real;
- •8.3 Нетипизированные файлы
- •Глава 9 Записи
- •9.1 Описание записи
- •I: integer;
- •9.2 Оператор присоединения
- •I, j, k, m : integer;
- •X: real;
- •9.3 Вложенные записи
- •9.4 Записи с вариантами
- •Information: record
- •I, k, n : integer;
- •Vedom : Array [1..Nmax] Of Stud;
- •I,j : Integer;
- •Vedom : File Of Stud;
- •Vedom : File Of Stud;
- •I,j,kdv,k2 : Integer;
- •If Not Eof (Ftel) Then
- •If Not Eof(Ftel) then
- •If Not Eof(FilComp) then
- •Глава 10 Динамические структуры данных
- •10.1 Распределение памяти при выполнении программ
- •Верхняя граница памяти ms-dos
- •10.2 Ссылочные переменные
- •10.3 Процедуры управления кучей
- •10.4 Использование переменных ссылочного типа
- •I: Integer;
- •I, k : Integer;
- •Val(b, k, code);{Превратили второй символ в ч исло}
- •10.5 Списки
- •Var Ch : Char;
- •Var Ch : Char;
- •10.6 Деревья
- •10.7 Константы ссылочного типа
- •Глава 11. Язык Паскаль. Графический модуль Graph Список используемой литературы Основная
- •Дополнительная
I, k : Integer;
a, b:Char;
code : Word;
Begin
Assign(f, 'Dat3'); Assign(f1, 'Dat1');
Assign(f2, 'Dat2'); {Связали файловые переменные с физическими файлами на диске}
Reset(f);
Reset(f1);
Reset(f2); {Открыли файлы на чтение}
While Eof(f) = false do {Организуем цикл}
Begin
Read(f, a, b);{Считали из текстового файла два символа}
Val(b, k, code);{Превратили второй символ в ч исло}
If a = 'i' Then
Begin {Блок для работы с объектом типа "игрушка"}
New(lg);
Seek(f1, k); {Установили указатель файла на компонент к}
Read(f1, Ig^);
Writeln;
With Ig^ Do
Begin
Writeln('HanMeHOBaHne '.Name);
Writeln('Цена'.Cost);
Writeln('Hижняя возрастная граница ', Age1);
Writeln('Верхняя возрастная граница ', Age2);
End;
Dispose(lg);
End
Else
Begin
{Блок для работы с объектом типа "багаж"}
New(Ba);
Seek(f2, k);
Read(f2, ВаЛ);
With ВаЛ Do
Begin
Writeln('Количество ', Count);
Writeln('Bec ', W:8:2);
End;
Dispose(Ba);
End;
End;
Close(f);
Close(f1);
Close(f2);
End.
До тех пор, пока не будет достигнут конец файла f, считываются два символа а и b. Символ а указывает на то, с какой структурой придется работать. Символ b содержит номер компоненты типизированного файла. Перемещение на k-ую компоненту файла осуществляется с помощью функции Seek.
10.5 Списки
Главная возможность, которую предоставляет наличие ссылочных типов и ссылочных переменных в Паскале, - это возможность построения г my помощью объектов со сложной, меняющейся структурой. Примерами таких структур являются списки, стеки, деревья.
С
писок
- это набор записей, каждая из которых
имеет поле данных и указатель (ссылку)
на следующую запись в списке. Та, в свою
очередь, тоже содержит поле данных и
ссылку на продолжение списка. Последний
элемент списка содержит значение
Nil,
т.е. уже ни на что не ссылается. Начало
списка формирует переменная типа
"указатель", содержащая адрес
первого элемента списка (рис. 10.4). Поле
данных еще называют информационной
частью списка.
Указатель в списке должен быть типизированным. Базовым типом для него является тот же тип данных, что и тип информационной части списка.
Рассмотрим методы работы со списками, информационная часть которых состоит из одного поля типа Integer. Такие списки естественно называть списками целых чисел. Обозначим тип элемента списка идентификатором Elem, а ссылочный тип на элемент списка – идентификатором
Рисунок 10.4 Линейный однонаправленный список
Type
Uk = ^Elem; {Описание типизированного указателя}
Elem = record{Описание базового типа}
х : Integer;
next : Uk;
End;
Var
p, q : Uk;
В Паскале допускается описывать сначала типизированные указатели, а затем уже их базовый тип.
Построим список из трех элементов, содержащих числа 5, 12 и -8. Список обычно задается указателем на свой первый элемент. Назовем этот указатель р. Значением переменной р в процессе построения всегда будет ссылка на первый элемент уже построенной части списка. Переменная q будет использоваться для выделения памяти под размещение новых элементов списка. Выполнение оператора р := Nil приводит к созданию пустого списка. После выполнения операторов
New(q);
q^.x := -8;
q^.next := р;
р := q;
имеем
список, состоящий из одного элемента,
содержащего число -8 в информационной
части. Ссылка на этот элемент является
значением переменных р и q.
Выполнение
операторов New(q);
q^.x
;= 12; q^.
next
:= p;
p
:= q;
приводит к тому, что в начало этого
списка добавляется новый элемент,
содержащий число 12; значением переменных
р и q
является ссылка на первый элемент
списка.
После выполнения операторов New(q); q^.x := 5; q^.next := р; р := q, добавляющих в начало списка элемент, содержащий число 5, построение списка завершается.
Значением переменных р и q является ссылка на первый элемент списка. Значение Nil поля next элемента, содержащего число -8, является признаком того, что этот элемент - последний в списке.
Если значения -8, 12, 5 вводить с клавиатуры, то программа построения списка будет состоять из следующей последовательности операторов:
Туре
Uk = ^ Elem;
Elem = Record
х ; Integer;
next : Uk;
End;
Var
p, q : Uk;
i : Integer;
Begin
p := Nil;
For i := 3 downto 1 do
Begin
New(q); {Выделение памяти для элемента списка}
Readln(q^.x); {Ввод численного значения информационной части}
q^.next := p; {Запомнили адрес предыдущего элемента списка}
p:=q; {Запомнили адрес текущего элемента списка}
End;
End.
Заполнение списка начинается с конца списка.
Основными операциями над списками являются:
переход от элемента к следующему элементу;
включение нового элемента в список;
исключение элемента из списка.
Пусть значением переменной q типа ссылка является ссылка на элемент списка целых чисел, описанного выше. Тогда после присваивания q := q\ next ее значением будет или ссылка на следующий элемент этого списка (если такой элемент имеется) или Nil. Пользуясь таким способом перехода от одного элемента к другому, можно просматривать весь список или его часть. Для того, чтобы вывести числа, содержащиеся в элементах списка, нужно выполнить последовательность операторов
q := р;
While q <> Nil do
Begin
Write(q^.x); q := q^.next;
End;
По ходу выполнения цикла While q <> Nil do ... значением переменной q является поочередно ссылка на первый, второй, третий и т.д. элементы списка и, наконец, Nil.
Пусть имеются переменные р, q, r типа ссылка и значением переменной q является ссылка на некоторый элемент списка целых чисел, а значением р -ссылка на первый элемент этого списка. Требуется включить в данный список после элемента, ссылка на который является значением переменной q, новый элемент, содержащий число 17. Для этого нужно выполнить последовательность операторов:
New(r); r^.х := 17; r^.next := q^.next; q^.next := r;
Пусть значением q является ссылка на некоторый (не последний) элемент списка целых чисел и требуется исключить из списка элемент, следующий за тем, ссылка на который является значением переменной q. Для этого нужно выполнить последовательность операторов:
r := q^.next; q^.next := q^. next^.next; r^.next := Nil;
Второе из этих присваиваний - исключение элемента из списка. Первое присваивание выполняется для того, чтобы сохранить ссылку на исключенный элемент. В этом случае элемент останется доступным и с ним можно выполнять нужные операции, например, освободить занимаемую им память с помощью Dispose. Третье присваивание выполняется для того, чтобы сделать исключение окончательным, т.е. чтобы из исключенного элемента по ссылке";} нельзя было попасть в список, из которого этот элемент исключен.
Процедура, исключающая из списка элемент, ссылка на который r:
Procedure exclude(Var p : Uk; r : Uk);
{р - указатель на первый элемент; r - указатель на исключаемый элемент}
Var q : Uk; {текущий указатель}
Begin
If p = г then p := г".next
else
Begin
q := p; While q^.next О г Do q := q^.next;
q^.next := r^.next;
End;
r := Nil;
End;
Для того чтобы включить в начало списка новый элемент, содержащий!) число 17, нужно выполнить действия:
New(r); r^.х := 17; r^,next := р; р := r;
Для исключения первого элемента из списка нужно выполнить:
r := р; р := p^.next; r^.next := Nil;
То, что включение (или исключение) в зависимости от местоположения элемента в списке выполняется по-разному, доставляет неудобства при программировании. В программах приходится предусматривать дополнительные проверки для того, чтобы выполнить включение или исключение одним из двух способов. Чтобы сделать действия единообразными, применяется следующий прием. В начало каждого списка добавляется заглавный элемент. Он никогда не исключается из списка, и перед ним в список не включаются новые элементы. Информационная часть заглавного элемента или не используется вообще, или используется для специальных целей. Например, в случае целых чисел она может содержать число, равное количеству элементов списка. Добавление заглавного элемента в список приводит к тому, что у всех элементов имеется предшественник, и действия по включению новых элементов в список проводятся одним способом.
Мы рассмотрели линейный однонаправленный список. Двунаправленный список называется очередью (рис. 10.5). Очередь - линейный список, элементы в который добавляются только в начало, а исключаются только из конца списка ("первым пришел - первым ушел"). Каждый элемент структуры содержит указатель на следующий элемент и еще на предыдущий. Считается, что для этого списка не существует обход элементов. Доступ возможен только к первому и последнему элементам, как в любой очереди в магазине. Очередь определяют два указателя: указатель на первый элемент списка и указатель на последний элемент списка. Начало списка называют хвостом очереди, а конец списка - головой очереди.
Рисунок 10.5 - Схематическое изображение очереди
Стек - линейный список, в котором добавления и исключения элемента производятся с одного конца, называемого вершиной стека (рис. 8). Соблюдается принцип "первым пришел - последним ушел".
Рисунок 10.6 - Стек
Считается, что доступ возможен только к верхнему элементу (в списках мы называли его первым). Стек оптимален для случаев, когда требуется просчитать и запомнить большое число структур данных, а потом обработать их в обратном порядке.
Работа со стеком осуществляется через указатель стека. При выполнении загрузки элемента в стек данные записываются на место, определяемое указателем стека, а указатель стека изменяет свое состояние и задает следующую свободную ячейку блока памяти. При извлечении элемента из стека указатель стека возвращается назад на один шаг. Добавить элемент в стек:
New(q); Readln(q^.x); q^.next := р; р := q;
Считать значение элемента из стека и исключить его из стека:
q := р; р := q^.next; у := q^.x; dispose(q);
Считать элемент, не удаляя его из стека:
y := Р^.х;
Списки могут быть не только линейными, но и кольцевыми. В кольцевом списке для последнего элемента следующим является первый, а если список двунаправленный, то для первого предыдущим является последний. Как и линейный, кольцевой список определяется указателем на свой первый элемент. При просмотре линейного списка переход от одного элемента к другому осуществляется до тех пор, пока рабочий указатель не станет равен Nil. При просмотре кольцевого списка надо переходить к следующему элементу до тех пор, пока рабочий указатель не совпадет с указателем на первый элемент. Поэтому первый элемент должен обрабатываться отдельно, а просмотр при помощи цикла следует начинать со второго элемента.
Мультисписки представляют собой структуру, каждый элемент которой входит в более чем один список одновременно и имеет соответствующее числу списков количество полей связи. Часто в виде мультисписков представляют матрицы очень большой размерности, в которых большинство элементов равны 0 (такие матрицы называются разреженными). Мультисписки • обеспечивают эффективное хранение таких структур в памяти: хранятся только те элементы, которые отличны от 0. Каждый элемент входит в два списка: в список-строку и список-столбец. Вся матрица представлена m + nсписками, где тип- соответственно число строк и число столбцов матрицы, каждый элемент хранит значение элемента матрицы и две ссылки: на следующий элемент в строке и на следующий элемент в столбце, указатели на начала этих списков хранятся в двух массивах. Описание типа данных одного элемента матрицы-мультисписка аналогично описанию элемента-очереди или узла дерева. Для описания матрицы потребуется два массива - массив указателей на первые элементы списков-строк и на первые элементы списков-столбцов.
Пример 10.6 Написать программу, обрабатывающую очередь пассажиров, желающих купить авиабилет. Элементы очереди содержат следующую информацию: фамилия пассажира, пункт прибытия, дата вылета. Информация об имеющихся билетах хранится в списке; элементы которого содержат номер рейса, пункт прибытия, дату, число непроданных билетов. Пассажир, обеспеченный билетом, удаляется из очереди. Содержимое списка по мере обеспечения пассажиров билетами корректируется.
Program Task1;
{Типизированная константа men содержит пункты меню основной части программы}
Const
men:array[1..8] of string[30] = ('Сформировать новый список','Добавить в список', 'Сформировать новую очередь','Добавить в очередь', 'Купить билет','Вывести список','Вывести очередь','Конец работы');
Type
Uk - ^Elem;
Elem = Record{Описание элемента'очереди)
Pred : Uk; Fam : String[10]; Punkt : String[10]; Date : String[5]; next : Uk;
End;
Sp = ^Elemi;
Elemi = Record{Описание элемента списка}
N : integer;
Punkt : String[10];
Date : String[5];
Count : Integer;
next : Sp;
End;
Var
o1, o2, o3 ; Uk;
s1, s2 : Sp;
{o1 - указатель на начало очереди, о2 - текущий указатель, оЗ - указатель на конец очереди, s1 - указатель на начало списка; s2 - текущий указатель}
a, i : integer;
Procedure Spisok;