- •1.1. Основные этапы создания программы
- •1.2. Алгоритмы
- •2.1. Структура типов в Turbo Pascal
- •Стандартные скалярные типы. Типы целых чисел
- •2.3. Операции побитовой обработки
- •2.4. Представление вещественных чисел в эвм
- •2.5. Символьный тип
- •2.6. Булевский тип
- •2.7. Перечисленный тип
- •2.8. Интервальный тип (диапазон)
- •3.1. Структура программы на turbo pascal
- •3.2. Основные операторы языка
- •3.2.1. Простые операторы
- •3.2.2. Операторы ввода-вывода
- •3.2.3. Структурные операторы
- •3.2.4. Условные операторы
- •3.2.5. Операторы повтора (цикла)
- •4.1. Массивы
- •4.2. Строковый тип
- •4.3. Множества
- •5.1. Процедуры и функции
- •5.2. Процедуры и функции пользователя
- •5.3. Передача параметров по значению и по ссылке
- •5.4. Рекурсивные процедуры и функции
- •6.1. Структура модулей
- •6.2. Компиляция и использование модулей
- •7.1. Записи
- •7.2. Вложенные записи
- •7.3. Записи с вариантами (вариантные записи)
- •7.4. Файлы
- •7.5. Подпрограммы для работы с файлами
- •7.5.1. Процедуры
- •7.5.2. Функции
- •7.6. Примеры программ для обработки файлов
- •7.7. Текстовые файлы
- •8.1. Структура оперативной памяти для программ на Turbo Pascal
- •8.2. Динамические структуры данных
- •8.3. Основные процедуры и функции для работы с динамическими переменными
- •8.4. Динамика выделения памяти в куче
- •8.5. Линейные списки. Способы создания и обработки
- •8.6. Нелинейные списки. Способы создания и обработки
- •Библиографический список
- •Оглавление
- •394026 Воронеж, Московский просп., 14
8.6. Нелинейные списки. Способы создания и обработки
Деревья. Конечное корневое дерево T формально определяется как непустое конечное множество
164
упорядоченных узлов, таких, что существует выделенный узел, называемый корнем дерева, а остальные узлы разбиты на поддеревьев , , …,. Узлы, не имеющие поддеревьев, называются листьями; остальные узлы называются внутренними узлами.
В описании соотношений между узлами дерева используется терминология, принятая в генеалогических деревьях. В дереве все узлы являются потомками его корня, а корень является предком своих потомков. Корень именуется отцом корней его поддеревьев, которые в свою очередь будут сыновьями корня.
Важной разновидностью корневых деревьев является класс бинарных деревьев.
Бинарное дерево T – это такое дерево, которое либо пусто, либо состоит из выделенного узла, называемого корнем, и двух бинарных поддеревьев: левого и правого . Бинарные деревья не являются подмножеством множества деревьев, они полностью отличаются по своей структуре,
Различие между деревом и бинарным деревом:
- дерево не может быть пустым, а бинарное дерево может быть пустым;
- каждый узел дерева может иметь произвольное число поддеревьев, а каждая вершина бинарного дерева может иметь 0, 1, 2 поддерева;
- в бинарном дереве существует различие между левым и правым поддеревьями.
Примеры двоичных деревьев: генеалогическое (семейное) дерево, где у каждого человека есть потомки (мать, отец); схема теннисного турнира, где каждая игра – это вершина, обозначенная ее победителем, а предки – две предыдущие игры соперников; арифметическое выражение с бинарными операциями, где каждому оператору соответствует вершина, а операнды поддеревья.
165
Если двоичное дерево организовано так, что для каждой вершины справедливо утверждение, что все ключи левого поддерева меньше ключа , а все ключи правого поддерева больше его, то такое дерево будем называть деревом поиска. В таком дереве легко обнаружить заданный элемент, для этого достаточно, начав с корня, двигаться к левому или правому поддереву на основании лишь одного сравнения с ключом текущей вершины. Дерево поиска для заданной последовательности целых чисел 23, 17, 26, 32, 18, 6, 2, 5, 8, 29, 146 имеет вид:
program derp;
type ukaz = ^nod;
nod=record
inf: char;
count:integer;
166
left,right: ukaz;
end;
var r,p,d: ukaz;
ch:char;
{Формирование дерева поиска}
Procedure Sozd(var d:ukaz; ch:char);
begin
if d=nil then
begin
new(d);
d^.left: = nil;
d^.right: = nil;
d^.inf: = ch;
d^.count: = 1;
end
else
begin
if ch<d^.inf then sozd(d^.left,ch)
else if ch >d^.inf then sozd(d^.right,ch)
else
begin
d^.count:=d^.count+1;
writeln('Элементы повторяются');
end;
end;
end;
{Поиск в дереве заданного узла}
{Функция возвращает адрес найденного узла}
{Если заданного узла в дереве нет, то возвращается nil}
function find(var d:ukaz;ch:char): ukaz;
begin
if d=nil then find:=nil
else
167
if ch<d^.inf then find:=find(d^.left,ch)
else
if ch >d^.inf then find:=find(d^.right,ch)
else
find:=d;
end;
{Обход дерева поиска и вывод на экран значения его узлов}
Procedure obxod(var d:ukaz);
var i: integer;
begin
if d<>nil then
begin
obxod(d^.left);
{Символ на экран выводится столько раз, сколько он встречается в последовательности}
for i:=1 to d^.count do
write(d^.inf,' ');
obxod(d^.right);
end;
end;
begin
d:=nil;
repeat
writeln('Введите символ режима работы ');
writeln(‘+ - формирование дерева);
writeln(‘- - удаление элемента из дерева’);
writeln(‘> - обход дерева и вывод на экран значения его узлов);
readln(ch);
if ch in['+','-','>'] then
case ch of
'+': begin
writeln(‘Введите очередной символ,')
168
writeln(‘символ вводится со знаком +’);
readln(ch);
if ch in ['a'..'z'] then sozd(d,ch);
end;
'-': begin
writeln(‘Введите удаляемый символ,')
writeln(‘символ вводится со знаком -’);
readln(ch);
{Удаление элемента имитируется инкрементированием}
{счетчика p^.count}
p:=find(d,ch);
if p <>nil then begin
if p^.count>0 then
p^.count:=p^.count-1;
end;
end;
'>': begin
obxod(d);
writeln;
end;
end; {end case}
until ch='*';
end.
Контрольные вопросы и упражнения
1. Что такое статические и динамические переменные?
2. Что представляет собой ссылочная переменная, указанная переменная, информационное поле и поле ссылки?
3. Чем отличается использование процедур New(R) и GetMem(R,i)?;
4. Объясните механизм действия процедуры Release(R).
169
5. Как определить размер наибольшего непрерывного участка кучи? Как определить размер общего свободного пространства кучи?
Следующие задачи (6-30) решить для случая реализации списка в виде стека, очереди и двусвязного списка.
6. Сформировать список, содержащий вещественные числа. Найти:
- среднее арифметическое элементов этого списка;
- поменять местами первый и последний элемент списка;
- заменить в списке все вхождения заданного элемента на элемент .
7. Сформировать список, содержащий символьные переменные:
- проверить, упорядочены ли элементы списка по алфавиту;
- удалить из списка элементы с заданным значением.
8. Сформировать список, содержащий строковые переменные:
- подсчитать количество слов в списке, которые начинаются и оканчиваются одной и той же литерой;
- переставить местами два заданных слова.
9. Сформировать список, содержащий строковые переменные:
- подсчитать количество слов в списке, которые начинаются с той же литеры, что и следующее слово;
- удалить из списка элементы с заданным значением.
10. Сформировать список, содержащий строковые переменные:
- подсчитать количество слов, совпадающих с последним словом в списке;
- разместить рядом с заданными элементами их копии.
11. Сформировать список, содержащий вещественные числа:
170
- определить является ли заданный список пустым;
- вставить элемент в список перед заданным элементом.
12. Сформировать список, содержащий целые числа:
- сформировать новый список, который будет содержать положительные элементы исходного списка;
- не создавая нового списка, разместить сначала положительные элементы списка, а затем все остальные.
13. Сформировать список, содержащий целые числа, упорядоченные по возрастанию. Вставить заданные числа в список, не нарушая упорядоченности.
14. Сформировать два списка, содержащих целые числа:
- проверить их на равенство;
- определить, входит ли список в список .
15. Сформировать список :
- перенести в начало списка его последний элемент;
- перевернуть список , то есть изменить ссылки в этом списке так, чтобы его элементы оказались расположенными в обратном порядке.
16. Сформировать список :
- перенести в конец списка его первый элемент;
- в списке из каждой группы подряд идущих равных элементов оставить только один.
17. Сформировать список, состоящий из символьных переменных:
- вставить в этот список пару новых элементов перед последним элементом;
- разработать рекурсивную функцию или процедуру, которая подсчитывает число вхождений заданного элемента в список.
18. Описать процедуру, которая объединяет два упорядоченных по неубыванию списка и в один упорядоченный по неубыванию список.
171
19. Разработать рекурсивную процедуру или функцию, которая:
- находит максимальный элемент списка;
- удаляет из списка все вхождения заданного элемента.
20. Разработать рекурсивную процедуру или функцию, которая:
- удваивает каждое вхождение заданного элемента в список;
- находит среднее арифметическое значение элементов списка.
21. Многочлен можно
представить в виде списка, элементами которого являются коэффициенты при степенях многочлена. Используя такое представление:
- проверить на равенство два многочлена;
- вычислить значение многочлена при заданном .
22. Используя раннее рассмотренное представление многочлена:
- построить многочлен, являющийся производной исходного многочлена;
- найти сумму двух многочленов (предусмотреть приведение подобных членов).
23. Сформировать список, состоящий из целых чисел:
- описать процедуру, которая в списке заменяет первое вхождение списка (если такой есть) на список ;
- проверяет, есть ли в списке хотя бы два одинаковых элемента.
24. Разработать процедуры и функции, предварительно выбрав для представления данных соответствующую списковую структуру, для решения следующих задач:
- определить, симметричен ли заданный во входном файле текст (за ним следует точка);
172
- дана последовательность из не менее чем двух различных натуральных чисел, за которой следует 0. Напечатать в обратном порядке все числа между наибольшим и наименьшим числами этой последовательности.
25. Разработать процедуры и функции, предварительно выбрав для представления данных соответствующую списковую структуру, для решения следующих задач:
- дана непустая последовательность непустых слов из букв; между соседними словами – запятая, за последним словом - точка; напечатать все слова максимальной длины;
- дана непустая последовательность слов, в каждом из которых от 1 до 12 строчных латинских букв; между словами
- пробел, за последним словом - точка; напечатать эти слова по алфавиту, указав для каждого из них число его вхождений в эту последовательность;
- решить предыдущую задачу в предположении, что максимальная длина слов не известна.
26. Дано произвольное натуральное число n. Напечатать все цифры десятичной записи числа n!.
27. Одно из возможных представлений «длинного» текста – это разделить его на участки (строки) равной длины и создать массив ссылок на эти строки.
Используя данное представление текста, описать:
- функцию для подсчета числа строк в тексте ;
- процедуру, меняющую местами - ю и - ю строки текста.
28. Используя введенное в задаче 27 представление «длинного» текста, разработать:
- процедуру, заменяющую - ю строку текста на копию - той строки;
- процедуру, удаляющую - ю строку из текста.
29. Используя введенное в задаче 27 представление «длинного» текста, разработать:
173
- процедуру, добавляющую после - й строки копию
-й строки;
- процедуру, печатающую построчно текст.
30. Разработайте структуру связанного списка, имеющего только один указатель на каждый узел, но позволяющую, тем не менее, перемещаться по списку вперед и назад.
31. Составить процедуру подсчета числа узлов заданного бинарного дерева.
32. Для заданного бинарного дерева описать процедуру или функцию, которая: определяет число вхождений элемента в дерево .
33. Вычислить среднее арифметическое всех элементов непустого бинарного дерева.
34. Заменить в бинарном дереве все отрицательные элементы на их абсолютные величины.
35. Поменять местами максимальный и минимальный элементы непустого бинарного дерева , все элементы которого различны.
ЗАКЛЮЧЕНИЕ
Завершая изложение основ программирования на языке Паскаль, следует отметить, что язык Паскаль является своеобразным аппаратом для распространения принципов эффективного программирования, которые в явной степени могут применяться и во многих других языках. К сожалению, в данном учебном пособии не нашли отражения вопросы машинной графики и объектно-ориентированного программирования. Однако успешное освоение основ программирования создаст необходимые предпосылки для самостоятельного изучения новых тем и закладывает основы для серьезной профессиональной работы по разработке программ.
174