Главная » Просмотр файлов » Структуры данных и алгоритмы

Структуры данных и алгоритмы (1021739), страница 18

Файл №1021739 Структуры данных и алгоритмы (Структуры данных и алгоритмы) 18 страницаСтруктуры данных и алгоритмы (1021739) страница 182017-07-10СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

Текст из файла (страница 18)

Таким образом, извлекая активационную запись из стека,для последнеговызова процедуры Р, можно управлять возвратом к точке в программе, из которой Рвызывалась (эта точка, называемая адресом возврата, помещается в активационнуюзапись процедуры Р при вызове этой процедуры).Рекурсивные вызовы процедур упрощают структуру многих программ. Но в некоторых языках программирования процедурные вызовы более "дорогие" (по времени выполнения), чем непосредственное выполнение операторов, поэтому программа можетработать быстрее, если из нее исключить рекурсивные процедуры. Здесь мы не выступаем в поддержку обязательного исключения рекурсивных или каких-либо иных процедур, очень часто структурная простота программы важна не менее, чем ее малое время выполнения.

На практике бывают ситуации, когда после реализации части программного проекта возникает необходимость исключить рекурсию, и основная цельэтого обсуждения заключается только в том, чтобы подвести к вопросу о том, как можно преобразовать рекурсивную процедуру в нерекурсивную с помощью стеков.Пример 2.3. Рассмотрим рекурсивное и нерекурсивное решения упрощенной версии классической задачи о ранце, где мы имеем целевое значение t и конечное множество положительных целых весов wlt u>2, •••, и>„. Необходимо определить, можноли из множества весов выбрать такой их набор, чтобы их сумма точно равнялась величине t. Например, если t = 10 и множество весов составляют числа 7, 5, 4, 4 и 1,то можно выбрать второй, третий и пятый веса, поскольку 5 + 4 + 1 = 10.В листинге 2.14 представлена функция knapsack (ранец), работающая с массивомвесов weights: аггау[1..п] of integer.

Функция knapsack(s,i) определяет, существуетли набор весов из множества весов от weights[i] до weights[ri], сумма которых равна s,и если есть, то печатает этот набор весов. В частном случае, когда s = 0, пустое множество весов считается решением. Если s < 0 или i > п (выход за заданное множество весов), то считаем, что решение не существует или не найдено (функция knapsackвозвращает значение false).Если ни один из перечисленных случаев к текущей ситуации не применим, то сновавызывается knapsack(s - ш„ i + 1), чтобы посмотреть, существует ли решение, котороевключает вес w,.

Если в этом случае решение существует, то оно является и решениемисходной задачи; это решение, включая wt, распечатывается. Если решения нет, то вызывается функция knapsack(s, i + 1) для поиска решения без участия веса wt. П2.6. СТЕКИ И РЕКУРСИВНЫЕ ПРОЦЕДУРЫ69•'•''р"...•'•'•.-И.?:'''''.'•'- .-.ГЛистинг 2.14.

Рекурсивное решение задачи о ранце(1)(2)(3)(4)(5)(6)(7)(8)/'^tV'-','!"function knapsack ( target: integer; candidate: integer) :.boolean;beginif target:= 0 thenreturn(true)else if (target < 0) or (candidate > л) thenreturn(false)else { ищется решение с и без candidate }if knapsack(target-weights[candidate], Candidate+1)thenbeginwriteln(weights[Candidate]);return(true)endelse { возможное решение без candidate }return(knapsack(target, candidate +1))end; { knapsack }Исключение „концевых" рекурсийЧасто можно чисто механически исключить последний вызов процедуры самойсебя.

Если процедура Р(х) на последнем шаге вызывает Р(у), то этот вызов можнозаменить оператором присваивания х := у и последующим переходом в начало кодапроцедуры Р. Здесь у может быть выражением, а х должно принимать значение, т.е.это значение хранится в локальной переменной. Если процедура имеет несколько параметров, то с ними надо поступить точно так же, как описано для х и у.Описанная схема вызывает повторное выполнение процедуры Р с новым значением параметра х с точно таким же конечным эффектом, какой был бы при рекурсивном вызове Р(у) и возврате из этого вызова.

Отметим, что тот факт, что некоторые локальные переменные процедуры Р принимают новые значения, не имеет последствий, поскольку процедура уже не должна использовать старых значенийэтих переменных.Подобный вариант исключения рекурсивного вызова можно проиллюстрироватьна примере листинга 2.14, где последний шаг функции knapsack возвращает результат рекурсивного вызова без параметров.

В такой ситуации также можно заменитьвызов операторами присваивания значений параметрам и переходом в начало кодафункции. В данном случае строку (8) в листинге 2.14 можно заменить следующимиоператорами:Candidate:= candidate + 1;goto beginningгде beginning (начало) — метка на оператор строки (1). Отметим, что параметрtarget не переприсваивается, так как сохраняет старое значение. Поэтому проверкиего значения в строках (1) и (3) фактически не нужны, необходимо только проверитьусловие, что candidate > п в строке (3).Полное исключение рекурсийОписанная выше техника исключения рекурсивных вызовов полностью удаляетрекурсии только тогда, когда рекурсивные вызовы находятся в конце процедур и вызов осуществляется в форме, позволяющей его исключить.

Существует более общийподход, позволяющий преобразовать любую рекурсивную процедуру (или функцию)в нерекурсивную, но этот подход вводит определяемые пользователем стеки. В общемслучае этот стек хранит следующее.1.70Текущие значения параметров процедуры.ГЛАВА 2. ОСНОВНЫЕ АБСТРАКТНЫЕ ТИПЫ ДАННЫХ2.3.Текущие значения всех локальных переменных процедуры.Адрес возврата, т.е. адрес места, куда должно перейти управление после завершения процедуры.В случае функции knapsack положение упрощается.

Во-первых, заметим, что привсех вызовах (при этом происходит вставка записи в стек) параметр candidate увеличивается на единицу. Поэтому мы можем хранить значение candidate как глобальную переменную, значение которой увеличивается на единицу при вставке записи встек и уменьшается на единицу при извлечении записи из стека.Во-вторых, следующее упрощение можно сделать, если в стеке хранить модифицированный адрес возврата. Отметим, что адрес возврата для этой функции можетнаходиться или в другой процедуре, вызвавшей knapsack, или в строке (5), или встроке (8).

Можно представить эти три возможности с помощью "статуса", которыйможет принимать три значения.1.2.попе (нет). Показывает, что вызов осуществлен из внешней процедуры.included (включенный). Указывает на вызов из строки (5), которая включает весweights[candidate] в возможное решение.3. excluded (исключенный). Указывает на вызов из строки (8), которая исключаетвес weights[candidatc] из возможного решения.Если мы сохраним статус как адрес возврата, то сможем рассматривать target какглобальную переменную. При изменении статуса с попе на included мы вычитаем весweights[candidate] из target и прибавляем его обратно при изменении статуса сincluded на excluded. Чтобы показать, что рекурсивно вызываемой knapsack найденорешение, используем глобальную переменную winflag (флаг победы).

Получив одинраз значение true, winflag сохраняет это значение, из стека извлекаются записи, и тевеса, которые имеют статус included, распечатываются. В описанной ситуации стекможно объявить как список статусов (statuses) следующим способом:typestatuses = (поле, included, excluded);STACK = { подходящее объявление стека }В листинге 2.15 приведена нерекурсивная процедура knapsack, оперирующая смассивом весов weights. Хотя эта процедура может выполняться быстрее, чем исходная рекурсивная функция knapsack, но видно, что код ее длиннее и она труднее дляпонимания.

Поэтому исключение рекурсий следует применять только тогда, когдаскорость выполнения программы является решающим фактором.Листинг 2.15. Нерекурсивная процедура knapsackprocedure knapsack ( target: integer ) ;varcandidate: integer;winflag: boolean;S: STACK;begincandidate— 1;winflag:= false;MAKENULL(S);PUSH(none, S);{ инициализация стека для рассмотрения weights[l] }repeatif winflag then begin{ извлечение записи из стека ипечать весов, входящих в решение }if TOP(S) = included then2.6. СТЕКИ И РЕКУРСИВНЫЕ ПРОЦЕДУРЫ71.writeln(weights[candidate]) ;candidate:- candidate - 1;POP(S)endelse if target = 0 then begin { решение найдено }winflag-.= true;candidate:= candidate - 1;POP(S)endelse if (((target < 0) and (TOP(S) = none))or (candidate > n)) then begin { решения нет }Candidate:= candidate - 1;POP (S)endelse { решения пока нет,рассматривается статус текущего кандидата }if TOP(S) = none then begin{ первая попытка включить кандидата }target:= target - weights[candidate];candidates candidate + 1;POP(S); PUSH(included, S); PUSH(none, S)endelse if TOP(S) = included then begin{ попытка исключить кандидата }target:= target + weights[Candidate] -,candidate:= candidate + 1;POP(S); PUSH(excluded, S); PUSH(поле, S)endelse begin { TOP(S) = excluded;отказ от текущего выбора }POP;(S);candidate:= candidate - 1enduntil EMPTY(S)end; { knapsack""}Упражнения2.1.2.2.2.3.Напишите с помощью операторов списка программу печати элементов списка.Напишите программы вставки, удаления и поиска элементов отсортированногосписка, используя для реализации спискаа) массив;б) указатели;в) курсоры.Каково время выполнения каждой из этих программ?Напишите программу для слиянияа) двух отсортированных списков;б) и отсортированных списков.2.4.Напишите программу объединения списков в один список.2.5.Рассмотрим многочлены вида р(х) = q*' + с2х' +•••+ с„х'-, где et > е2 > ...

> е„ >0.Такой многочлен можно представить в виде связанного списка, где каждаяячейка имеет три поля: одно — для коэффициента с(, второе — для показателя721гГЛАВА 2. ОСНОВНЫЕ АБСТРАКТНЫЕ ТИПЫ ДАННЫХ2.6.*2.7.степени eit третье — для указателя на следующую ячейку. Для описанногопредставления многочленов напишите программу их дифференцирования.Напишите программу сложения и умножения многочленов, используя ихпредставление, описанное в упражнении 2.5.Пусть ячейки объявлены следующим образом:typeсе11type = recordbit: 0..1;next: T celltypeend;Двоичное число bib2...bn, где каждое bt = О, 1 имеет десятичное значениеR2.8.*2.9.^Ь^"'1 . Это число можно представить в виде списка bi, Ьг, ..., Ьп.

Характеристики

Тип файла
PDF-файл
Размер
45,43 Mb
Тип материала
Высшее учебное заведение

Список файлов книги

Свежие статьи
Популярно сейчас
Почему делать на заказ в разы дороже, чем купить готовую учебную работу на СтудИзбе? Наши учебные работы продаются каждый год, тогда как большинство заказов выполняются с нуля. Найдите подходящий учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
6508
Авторов
на СтудИзбе
302
Средний доход
с одного платного файла
Обучение Подробнее