Лекции (984123), страница 12
Текст из файла (страница 12)
Для этого понадобится тип элемент стека, который содержит ссылку на следующую компоненту. Суре 1'11еш - 1Се1п; 1Сеп1 — гесоге1 <1аСа: '1'; ргем: Р1Сшп; епд; яСгпсС 1Сеш ( Т с1аСа; яСгисС 11сш* ргеъ-, ); 237 ГппсСюп Рпя!11ъ~аг я: яСас!г; С: Т): Ьоо1еап; Ьеиш К(я.
в!хе ..= РО01. о!ХЕ) СЬеп Рпяй: Га1яе е1яе Ьея1п я л1ага!я. я1хе ): С; я. я!хе: я. в!хе ~ 1; 1'пя11 ь - Сгпе; епе1; епе1; ГппсСюп Рор(ъаг я: яСас1с): Ьоо1еап; Ьеиш 11'(я. я1хе - О) СЬеп Рор: — Га1ее е1яе Ьефп я. я!хе: я. 81хс — 1; Рор: -- Сгпе; епе1; епс1; Ьоо! Рпв11(яСас1с* я, Т С) 11(я — >в1хе >-- РОО1 Я1ЕЕ) геСпгп Ыве; я — >с1аСа!в — >я|ге-'-+~ 1,; геСпгп Сгпе! С!ььяьо оьь?ьеХЬсььсььие стека, яак»ььоиаеьььи я описании цн?к ььереьисиььыгс укаяьчьетьи на перьпину стека и целой ььь рсмеььььой-глубинь.ь стека. Сурес?еГ яСгпсС ( яСгпсС ?Сеььья Сор; ьпС я!хс; ) я?ас!ь; Суре я?ас1ь -- гесогс1 Сор: Р1?епь; я!хе: шСедег; епс?; чоЫ СгеаСе(яСас?ь» я) ( я — >Сор - О; я — >я!хе -= О; ргосес1пге СгеаСе(чаг я: яСас!с); Ьефть я.
Сор: — п!1; я. я!хе:--.— О; епс1; КппсС?оп ЕшрСу(чаг я: яСас?ь): Ьоо1еап Ьоо! Еьпр?у(я?ас?с~ я) геСпгп я — >Сор -- О; Ьедш Еьпр?у: - я.гор - ьь!1; епс1; шС о!хе(яСас!»* я) геСпгп я — >я!хе: ГппсС?оп о!хс(чаг я; яСас!»); шСедег: Ьедш Я!хс: я, я!хе; епс1; СппсС?оп 1'ьья?ь?чаг я: яСас?ь: С: Т) Ьоо1еап; чаг 1; Р?Сеьп; Ьедш певуч Я; ьС' ! -- п!1 СЬеп Рьья?ь >- Ыяе е1яе Ьедш ! ".с1а?а:-- С; ,ргеч: - я.?ор; я. Сор: — ь; я. я!хе: = я. я!хе -с 1: Рпя?ь г= Сгпе; епс1; епс?; Ьоо! 1'ьья?ь(яСььс?ь»» я, Т С) яСгисС ?Ссььь»: ! пьа11оы(я?хео??яСгпсС ?Сеьп)); 1?'(! !) геСпгп ?а1яе; ! — >ь?аСа -- С: ! — > ргеч — я — >Сор; я — >Сор -- ь; я — >я!ге++; геСшп С,гпе; Кппс11оп Тор(айаг я: я1ас1с): Т; Ьеиш 1К(я.1ор <> 0) 1Ьеп Тор:-- я.1ор.с1а1.а: епс1; Т Тор(я1ас1~~ я) 11'(я — 1ор) ге1пгп я — >1ор — >с1а1а; Мы не приводим здесь программы ревс- эса стека, поскольку для этого всего лишь надо переместить все его элементы во вспомогательный стек, а затем скопировать эту вспомогательную стековую переменную в исходну.ю.
Инверсия элементов выполняется автоматически при занесении их во вспомогательный стек. Следовательно, стек может быть использован и для итеративного реверсирования очереди. Рекурсивный реверс стека, представляет лишь умозрительный интерес. В заключение еще ряз подчеркнем сходство функциональных спецификаций стека и очереди„различия между которыми также проявляются в их разпоголовочности: стек-- Гппс11оп Рор(таг я: я1ас1с): Ьоо1еап; тат 1: Р11,епц Ьеиш 11(я, я1хс 0) 1Ьеп Рор; — Га1яе е1яе Ьефп 1 ' я 1ор1 я.1ор: — я.1о1ь1тгет; я.
я1хе: — я. я1ге — 1; Йярояе(1): Рор 1гпе; епс1:, епс1; ргосес1пге Е)ея1гоу(ъ аг я: я1ас1с); айаг 1: Р11ещ Ьеиш и Ы1е(я.1ор <> шЦ с1о Ьеи1п := я.1ор; я.1ор: я.1ор.ргеи; с1гярояс( ~ ); епс1; я.1,ор: — ш1: я. я1хе: — 0: епс1; Ьоо1 Рор(я1ас1с~ я) 11 (! я — >я1хе) ге1пгп 1а1яе; я1гнс1 11спи 1 =- я — >1ор; я — 1ор я — >1ор — >ргем; я — >я1хе — —.
1гсе (1); ге1пгп 1гпе; тоЫ Рея1гоу(я1ас1с~ я) Мп1е (я — >1ор) я1гпс1 11егп~ 1 -- я — >1ор: я — >1ор - я — >1ор — >ргем; 1гес (1): я — >1ор - 0; я — >я1хе — 0; одноголовочная структура, а очередь лвухголовочная. Однако это рвзличяе, можно сгладить, моделируя двумя одпоголовочными стеками одну двухголовочную очередь. Определим операцию постановки в очередь через добавление в стек, а извлечение из очереди будем осуществлять путем выемки из первого стека верхнего элемента и помещения его во второй стек. Когда в первом стеке останется только один элемент, извлечем его и «перельем» содержимое второго стека обратно в первый. Нри этом две инверсии погасят друг друга, а, первый элемент очереди, лежавший на дне стека, в результирунлпую очередь не попадет.
Кстати, реализация очереди двумя стеками небессмыслена, т. к. в отличие от очередей, стеки имеют аппаратнунз поддержку во всех современных процессорах. Вспоминая дек (двухконцовую очередь), мы можем предложить еще одну его реализацию, базирующуюся на двух стеках или очередях, контролирующих общую последовательность. Верно и обратное: ограничивая разными способами функциональность дека, мы получим очередь или стек. Отечественная информатика обогатила, мировую сокровищницу жемчужиной встречных стеков, когда два стека располагаются навстречу друг другу в одном массиве, что позволяет двум стекам поочередно пользоваться общим свободным пространством, сохраняя простоту и быстроту отображения реализации стека на массив.
К сожалению, эта идея не обобщается на случай трех и более стеков. 5.6 Линейный список Линейные списки являются обобщением ранее изученных последовательных структур с ограниченным доступом: файлов, очередей и стеков [49, 20[. Они позволяют нам представить последовательность элементов так, чтобы, в отличие от очереди и стека, каждый элемент был бы дос супен и для этого пе нужно бьшо бы извлекать из структуры предшесгву1ощие элементы. В терминологии Д. Кнута [63[ линейные списки являются частным случаем нелинейных списков общего вида,, в число которых входят деревья, графы и другие произвольные с,тюжные структуры. Линейный список — это представ.ление в ЭВХ1 конечного упорядоченного динамического множества элементов типа Т. Точнее, это не множество, а иульпилмно:лссстео, т.
к. в последовательности могут находиться элементы с одинаковыми значениями. Элементы этого множества линейно упорядочешя, но порядок определяется пе номерами (индексами), как в массиве, а относительным расположением элементов [85[, Отношений порядка на этом множесгве может быть не одно, а. два, и тогда мы имеем дело с двусвязными (двусторонними или симметричными) списками, Для закольцевания списка необходимо доопределить в качестве следующего за последним первый элемент списка, а в качестве предыдущего первому элементу последний (голова указывает на хвост, а хвост на, голову). Таким образом отношения порядка, (предыдущий и,~или слелуклций) становятся определенными для всех смежных (с точностью до закольцевания) пар элементов списка, Список обозначается простым перечислением элементов в заданном порядке в круглых скобках через запятую.
Например, список 1 из пяти элементов типа Т выглядит так: ~ = (~~; гг. гз: г«; 4) Линейные списки естественно использовать всякий раз, когда встречаются упорядоченные множества переменного размера, где включение, поиск и удаление элементов должны 240 ВыпОлняться нс- сис1ема1ически В 1ОлОВс' и>!и хВОс11 как для фаи" н)В или стеков и В про извольных последовательно достигаемых местах, но с сохранениелл порядка следования остальных элементов.
Таким порядком могли бы быть, например, приоритеты, присвоенные заданиям, ожидак>щим обработки в операционной системе или распечатки на сетевом принтере; принцип очерс-'ди: первым пришел первым обслуживается, — нслгибок и недоста,точен. Для постановки приоритетного зада,ния в такук) сшередь, не<>бходимо последовательно пройти список с самого начала и вставить это задание перед первым элементом, имея)илим меньший приоритет. Заметиъл, что порядок следования элементов в списке не предполагает упорядоченности хранимых в этих элементах значений. Наиболее простой пример линейных списков в информатике -- списки переменных в описаниях: 1н$ х, у, з:, Фурес1еГ ВФгнс$ ( с1опЫе а; Ьоо! 1>; сЬаг с:, ВЬогФ 1пС с1: ) Я; Для поиска элемента в списке надо просматривать его с начала, сравнивая искомое значение со значением, содержащимся в очередном хранимом элементе.
В более сложном случае аргументом поиска (ключом) является одно из полей значения. 'Элементы списка не считаются пронумеровапныхли, но хложно прописать номера в дополнительных полях элементов (но при вставке и удалении номера необходимо снова вычислять ценой 0(Х)) или генерировать их при прохождении списка. Цена поиска элемента в линейном списке есть 0(Х): искомый элемент может с равной вероятностью находитьсл в любом месте списка от первого до Х-ого. Если элемент находится в начале списка, то для поиска надо сделать один шаг, если на втором месте два шага и т. д, Если элемент находится на последнем месте, то необходимо сделать Х шагов, !> среднем надо сделать 1-~ 21 ...4Ж Х(Ж41) %4!1 2>')1 2 шагов.
То есть список, как очередь и стек, является последовательной структурой с линейным временем доступа максимальным для линейных структур. Для некоторых нелинейных с)труктур (например, разреженных матриц, представляемых в виде списков списков элементов) время поиска элемента пропорционально Х~. Для добавления нового элемента в список необходимо указать значение, аеред (или после) которого надо сделать вставку. Для начала надо найти искомый элемент в среднем за Х/2 шагов (если такого элемента, в списке нет, то он обычно вставляется в конец списка). Если же искомый элемент найден, надо выполнить необходимый вариант вставки. Вставка спереди легче выполняется в двусвязном списке; в односвязном для этого требуется запоминание ссылки на предпоследний элемент. Вставка, сзади технически проще, здесь достаточно односвязного списка.
Вставка с'переди более логична,„например, при включении с сохранением порядка в упорядоченныс списки. В книге Н. Вирта (53~ приводятся 241 своеобразные технические приемы вставки и удаления элементов списка: вместо работы с элементами списка производятся манипуляции со значениями элементов (перестановка). Удаление элемента из списка обычно предваряется его поиском, занимаюгцим в среднем %~2 шагов.
Цена самого удаления обычно невелика и пропорциональна 0(1). Зеимечание. Вставка и удаление элемента очереди и стека обходится всего лишь в 0(1), что существенно дешевле среднесписочной 0(Х). Это плата за произвольность места, вставки и удаления. 5.6.1 Функциональная спецификация Полная функциональная спецификация двусвязного линейного списка 1 т объектов типа, Х достаточно длинна (72~: В левой части спецификации операции ВСТАВКА находится декартово произведение трех множеств: всевозможных списков, в которые должна быть проведена вставка, всех элементов перед которыми необходимо ее произвести и различных вставляемых элементов. Помимо тривиальных свойств типа: 1. ПУСТО(СОЗДАТЬ) =- багие 2. ПУС'1'О(ВСТАВКА(1, 1, 1) -- 1а1ае можно отметить следующие: 1.
ПРЕДЫДУЩИЙ(СЛЕДУЮЩИЙ(1)) -- 1 2. СЛЕДУЮЩИЙ(ПРЕДЫДУЩИЙ(1)) -- 1 Эти записи следует читать справа налево: каждый элемент является предыдущим к следующему за ним или следующим за предшествующим ему. 3. 1: — СОЗДАТЬ 1: — ВСГАВКА(1, 12, 1а) 1: — ВСТАВКА(1, 1ъ, 1,) ПЕРВЫЙ(!)-- ПОСЛЕДНИЙ(1) 242 СОЗДАТЬ: ПУСТО: ДЛИНЛ: ПЕРВЫЙ: ПОСЛЕДНИЙ: СЛЕДУЮЩИЙ: ПРЕДЫДУЩИЙ: ВСТАВКА: УДАЛЕНИЕ: УНИЧТОЖИТЬ: 1 т — ~ Ьоо1енп ~'т Ьт-т 7т--Т 1тхт- 7' 1тхт — ~7" 1т х7'х Т вЂ” «1т 1т х 1 — '1т 1т — '~ .