Лекции по информатике (984119), страница 8
Текст из файла (страница 8)
с рекурсивным разбором очередтього тьодвььраоьсения ) е1ве с1опе: — Сгпе; епс1; ехрг: = ех; епс1; Ьедш рагве: ехрг; епс1; (рагзе) Ье~1п (ргоутат) ехрг1гее:-- рагае; рг1п11гее 1ехрг1 гее); ь1ев1гоу1гее 1ех1ьгСгее); епс1. Другой пример — преобразование выражеьгии из инфиксной формы в постфикснукх ргоигаш ш2ровСЬ'1ььрп1, опгрп1); ргосес1пге Сгеаге(чаг в: Я1ас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с): чаг а1: ЯСас1ц ( При преобразовании из инфиксноУь сборлььь в ььосттьфикстьую помимо вььтьььса знака отьсрацтии назад, необходильо упорядочивьипь операции согласно 'их прпоритеталц в том числе и в связтл с отказом от скобок.
Длл необходимой инверсии порядка выполнения операиий и будет использован стек ) с, и: сЬаг; : шСедег; ( Фу>скция сравнивает приорителпы, операций, оказавшигося рядом в абра>пнои польской записи, ~ ГппсС1оп ргсс1[с1, с2; сЬаг): шСедег; Ьее:ш ргсс!; — О; ( Умнов>сение и деление приоритетнее сг>озюенья, и вычитания г' 11' [с>1 ш ['*', '>" [) апс1 [с2 ш [' -', ' — ')) СЬеп ргс>1; 1; 11' [с1 ш ['-, ', ' — '[) апс1 [с2 ш ['*', ',>'[) СЬеп ргсс1; — 1; ( Одинаковые операции имею>п одиникос>ь>й приоритет >> 11' [с1 ш [' — , '',' — '[) апс1 [с2 ш [' — '',' — '[) СЬеп ргсс1: — О; 1Г [с1 ш ['*', '>" [) апс1 [с2 ш ['*', '>" [) СЬеп ргсс1: — О; ( Открывающая скобка имеет, высший приоритет (мультипликативный[ ...
3 11' [с2 -- '[') ог [с1 — '[') СЬеп ргсс1:-- 1; а закрывающая — низший (аддитивнъ>й) 3 11' с1 =- ') ' СЬеп ргсс1: = — 1; епс1; ( Преобразование константного вь>раз>сения из десятичнъ>х цифр в постфиксную запись Г Ьедш Сгеаге[зг); ( Создание стека откладъ>ваемъ> с операций ~Г ~»Ь11е поС ео1п с1о Ьедш геас1 [с); 11' с ш ['О' .. '9'[ СЬеп ( операнд / жг1Се[с) е1ве Ьеа:ш ( Знак с>псраипи апс1 (стек пуст (отлов>сс>ннъи; операции неча) оз текущая операция, формулы г>риоритетнс>е отлозюенной в сгпек) ~~ 11' [е ш [' 1 ',' — ',.'*'.,' '[) апс1 [Е>г>ргу[зГ) ог [ргсс1[с, Тор[зС)) > О)) СЬеп РпзЬ[с) ( Операция заносится в стек ~Г е1ве Ьею1п жЬ11е [поС Е>г>рсу[зС)) апс1 [ргссЦс, Тор®) < — О) с1о Ьее1п ( Вынимаем нз стека, операц>ао и пенагпаем ес., если она не приоритегпнее текущей операиии с,1 х ъ-- Тор>зг); Рор[зг); если только зто не скобка г' 1К х <> '[' СЬеп ът1Се[а); епс1; ( Помещаем в стек текущую операцию, если только это не скобка 3 11' с < > ') ' СЬеп р>ге!1[с); епс1; 282 епс1:, епс1: 1' Опустошаем стоек, печатая отяоои;енньне операции е порядке, обратном с<х наступлению ~ ч«Ы1е поФ Е>п1йу(аС) с1о Ьеи1п 11 Тор(вс) <> '(' $1теп Ьеи1п и<гйе(Тор(ас))1 Рор(ас); епс1; епс1; и<гЫе1п; 1)еасгоу(ас); епс1.
5.10.5 Обход дерева общего вида Деревья общего вида имеют более сложную структуру, чем двоичные, и их обход в силу произвольности числа, разветвлений каждого узла пе может быть также легко перенаправлен по двум алыернативам налево и направо. Требуется цикл или рекурсия по переменному числу разветвлений.
Чтобы перебрать всех сыновей, надо просмотреть до конца их очередь. При этом возможны два приорит<'та; сначала перебираются братья (обход в ширину) или сыновья (обход в глубину). Если представлять дерево общего вида как двоичное, то поиск в глубину аналогичен КЛП-обходу. Для обхода в ширину двоичного аналога нет. 1. при поиске в глубину: (а) если дерево пусто,то конец обхода; (Ь) берется корень; (с) выполняется поиск в глубину для поддерева старшего сына: (с1) выполняется поиск в глубину для следующего брата. 2.
при поиске в ширину: (а) поместить в пустую очередь корень дерева; (Ь) если очередь узлов пуста,то конец обхода; (с) извлечь первый элемент из очереди узлов и поместить в ее конец всех его сыновс',й по старшинству: (<1) повторить поиск начиная с и. 2Ь. 5.11 Деревья поиска Двоичные деревья часто употребляются для представления множеств данных, элементы которых должны быть найдены по некоторому клк>чу (полю данных) ~541 Если дерево организовано так, что для каждой вершины Х< справедливо утверждение, что все ключи левого поддерева Сг меньше ключа Ц, а вес ключи правого поддерева 1) болыпе его, то такое дерево называют деревам поиска.
В таком дереве можно быстро обнаружить элемент с заданным ключом: надо начиная с корня двигаться к левому или правому поддереву на основании лишь одного сравнения с ключом текущей вершины. 11о построениго дерева, НОиска. Пе1юхОдя к Одному из НОддеревьев, ыы автОыатически исклк) гаем из 1гассмОтрения другое поддерево, содержащее половину узлов. При дальнс;йгпем рассмотрении исключается половина, половины и т. д. Тем самым будет выполнено исключение из рассмотрения подавляющего большинства элементов дерева, кроме вершин, по которым идет принятие решения о направлении поиска, причем чем соалансированнее дерево, тем большее число узлов будет исключено из поиска. Число таких вершин для сбалансированного двоичного дерева не может быть больше его глубины, оцениваемой как 1оя, и.
11оэтому деревья поиска, дают существенный выигрыш во времени поиска по сравнению с линейными структурами: 1оаэ п « и. Например, для и = 2048 выигрыш будет почти в 100 раз, и гиинуты превратятся в секунды! Более того, поскольку поиск идет от корня дерева и до его листа, по однозначно выбираемому пути, то для его реализации достаточно одного цикла с предусловием, а рекурсия и ее верный оруженосец стек могут отдохнуть: ГппсСюп 1осаге(х: шСепег: г: р): р: Ьеиш )УЬ11е (С <.= Н11) апс1 (г .1сеу <'> х) с1о 11' С .1сеу < х СЬеп С: — С".г е1ве С г.
г,".1; 1о саге: — С епс1; В случае неуспеха, когда в дереве с корнем С пе было обнаружено ключа со значением х, функция !Оса!е(ал С) получает значение ш1. В эту процедуру поиска мс)жет быть внесено усовершенствование. Для упрощения усло- вия поиска можно, также как и в списках, ввести терминируклций элемент а )', к кото- рому гамаком ~54~ привязать пустые (нсиспользуемые, кроме как для прошивки) ссылки всех концевых всрп)и)) дерева поиска. В результате из условия поиска удаляются два из трех сравнений.
В предусловии цикла остается только сравнение с барьерным элементом. 11равда, в случае неудачного поиска функция примет значение не ш1, а будет указывать на якорь нашей древовидной структуры, что придется учесть при использовании моди- фицированной процедуры 1осаге О, ГппсСюп 1осаге(х: шСе~ег:, г; р); р:, Ьеп1п а .1геу: х; 1' барьерное значение заносится о баръерггълг1 злеллепт, 3 лУЬ11е ~11 <> пг1) аглг1 )г (г .1сеу <> х) с1о 1' гуслооие ггнрощсно на 2уЗI )г 1С" С .1сеу < х СЬеп С: - С".г е1ве : -- С".1; 1о саге:. г епс1; 284 Справедливости ради необходимо заметить, что, ускоряя поиск, техника барьерного элемента усложняет более редкие, чем поиск, процедуры вставки и удаления элементов. 5.11.1 Поиск по дереву с включениями Динамическое распределение памяти особенно удобно там, где структуры данных нелипейны и меняются с течением времени.
Рассмотрим сначала случай, когда дерево поиска только растет. Хрестоматийная задача такого рода — построение и обслуживание частотного словаря [54). Требуется определить частоту вхождения каждого из слов в последовательность, поступающую из входного гекстового файла. Надо либо найти слово в дереве и добавить ! к находящемуся в соответствующем узле счетчику его вхождений, либо, в случае неуспеха, включить новый элемент в дерево с сохранением нелинейного иерархического порядка и поисковой структуры и ус:тановить для пего единичное значение счс!тчика. !!усть элемент дерева, псьчска имеет следующее рекурсивеюе Опистисие: Суре ир == яогс1; я огс1 — гесогс1 1сеу: шСеиег; сошй: шСеиег; 1, г: юр епс1; Программа поиска по дереву с включениями может выглядеть так.
геас11п(х); Мп1е поС сои с1о Ьеи1п аеагсЬ~х, гооС); геас11п(х) епс1; Процедура поиска с включением веагс6() сначала должна осуществлять поиск в деревс' аналогично процедуре 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; г: — гл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ееу, .гоей) епс1: рг1лйггее1гоо1, 01 епс1. Параметр р передается в процедуру аеатс6 не по значению, а как переменная, поскольку в случае включения нового элемента в дерево поиска, необходимо вернуть ссылку на этот элемент, как будто ебы он только что был найден в модифицированном дереве.