Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Praktikum_po_programmirovaniyu.doc
Скачиваний:
23
Добавлен:
09.12.2018
Размер:
2.5 Mб
Скачать

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