Искусство программирования на Си (984073), страница 37
Текст из файла (страница 37)
В таком случае его следует уничтожить реве: В начале этой главы был рассмотрен метод построения пабе = пабе->г[чвс) При этом необходимо уничтожить казкдый узел дерева ггг лпе ьлп поппе[сапов аегпес ьлп егап *агап) двоичного дерева из сортированного списка. В резуль) и сал<у его структуру. Уничтожение всех узлов верею< 221 тате такого подхода мы всегда получали двоичное дсЗдесь я[пей является л<ассивол< указателей на узлы, можно выполньпь с помошью еше одной рекурсивноц 224 аавегс(егее <= НОЬЬ)) рево минимальной высоты.
Но это достаточно редкий которые составляют содержимое стека. а соцш — коли- функции. На лот раз нужно убедиться, что мы не по 225 геспгп Егее->Соппс[ случай. В реазьной жизни всегда придется до валять и . В й б чество указателей в стеке на данный момент времени. лучим ркютупа к уни по:кенному узлу. Для этого проудалять узлы. Если бы такая возможность не требова(Слсловательно, если сопя( больше нуля. верхним ука- ше всего выполнить обратное прохождение, в отли ше Этот код нс требует объяснений. лась, можно было бы просто использовать сортированзателсм в стеке является Маей[сопл(-)!.) от прямого прохождения, которое осуществляется ь ный список, поскольку с пил< легче ра отать. б Новыи код в цикле выполняет явное солраненис фу ' И ) р р ф нкциях аи! иа[Ц) и аи! [гатегяе().
П и обратном Анализ Предположим, что мы начинаел< с пустого двоичного текушсго значения поде. Если значение поде ненулевое, прохожлении мы сначала рскурсивно выполняем деп В начале этой главы причиной рассмотрения двоично- лсрева, в которое добавляем узлы до тех пор, пока деоно сохраняется в стеке, а значение поде заменяется стане над хая<выл< полдеревом узла, а затсл< наз сачнч голерева была названа низкая скорость поиска по спис- Р ево не будет содержать все необходимые данные.
Предзначснисм цобе->[е[[, после чего выполнение функции узлом. Это легко реализуется следуюшим образом: ку. Теперь необходимо еше раз более точно оценить положим, что добавление узлов осушсствляетси случайначинастся сначала. Если значение побп упсвОе, фун 2О4 асасас чозб баасгау(асгпес Ьап паба *паба) скорость поиска по двоичному дереву, чтобы убедить- ным образом.
Что это будет означать для функции кция восстанавливает прсдыдушсе значение побе и вы- 205 ся, что оно действительно обеспечивает ту скорость, на Ейп [пает[()у На каждом этапе вероятность тогр, по знаполненис продоях астся. При отсутствии предыдушил 206 1[ (пабе == нпьь) которую мы рассчитывали. ченис добавляемого элемента будет больше или мснь- 208 бевггоу(пабе->Ье[Е); В римере игры "Угадай и.
о" на каждом уровне шс значения узла, составляет по 50% Это означает, что го сллчая легче мыслить в обратном порядке. Если у х жит максиманьное значение в дереве. Эти указатели ! но указателя. указываюшего на ролительский узел дан- есть наследник у, то х является предшественником у. будут единственными нулевыми указателями в дереве. ного узла. Если зто не корневой узел, то указатель на Прн необходимости найти предшественника у, нужно Несомненно, будет необхолимо различать обычные г родительский узел будет ненулсвыль было бы использовать минимальное значение левого связи и ссылки.
В результате в структуру каждого узла Лля этого придется измени~ь структуру Ыгпсг гншлерева узла у. Аналогично, чтобы найти наследника вводятся два дополнительных бита, которые позволят 2 Ьгп поде. Процесс изменения, как вилно из листинга узла, требуется найти минимальное значение в его пра- отличить связь от ссылки. 12.2, является довольно простым. вом поддереве. Для этого от узла у следует двигаться в На основании приведенного описания можно объянаправлении вниз и влево. а затем вправо до тех пор, вить структуру такого узла, как это показано в листиндвоичного дерева с указателями на родительские пока не закончатся правые поддеревья. ге 12.3. 5 з узлы. Этот путь можно пройти в обратном направлении, двигаясь вверх и влево ло тех пор, пока имеется такая Листинг 12.3.
1Ь1п.с — стРУктУРа Узла ДлЯ 31 втгасс РЫв лабе 1 а! ог 32 1ас бата; возможность а затем сделать один швг вверх и яправо двоичного дерева со ссылками Обрагите внимание, что на каждом этапе есть только 31 вегасе сЫо аобе 1 РИСУНОК 12 4. Два вида вырожденного двоичного дерева, 34 вегасе рЬ«п пабе *глдЫ; один путь, по которому можно идти вверх. Поэтому мы 32 зас бата; 35 вегасе РЬлп поде «рагеас; просзо анализируем, в каком направлении двигаемся, и Какого-либо одного простого решения указанной 34 1' если это был шаг вправо, то процесс необходимо завер- 34 асгасс тЫп лабе «гздЫГ 35 аавлялеб 1 тьгеаб:1; проблемы, нс сушествуст.
Если ваше приложение будет шить. Процесс также завершаетсл, если больше нет уз- 34 алв1аавб г Сьгеаб«1; вставлять элементы в двоичное дерево цреимущестлен- Назовсм измсненнук«структуру узла зтпгсг РЬ1п пабе. лов, поскольку это говорит о том, что х представляет зт 1; но в отсортированном порядке, то простое лвоичнос Кроме того. аналогично структуре Ь1п Ггее, можно собой элемент дерева с максимальным значением. Организация данина Часть Н Дерево такого вида является деревом с полными час, хотя мы и нс получаем дерева с минимально воз- Х)ы легко можем создать структуру узла АЪЕ-дорс- Вставка ссылками )н)ожно также определить понятие двоично- можной высотой в ка:кдый момент времени, тем не ва на языке С (листинг 12.4). Вставка узла в А1)Е-дерево намного сложнее, чем вставго дерева с нрааымн ссыгнами, в котором пустые правые менее, находимся близко к минимуму.
указатели на дочерние узлы каждого узла заменяются А)гЕ-дерева и дерево гег)-Ыасй задаются различными Листинг 12.4. атйс — структура узла АЧЕ-дерева. ка узла в простое двоичное дерево поиска. Пооцссс ссылками, а левые не заменяются. В дереве с полными наборами критериев, в соответствии с которыми деревставки узла можно разбить на ~стыре э~апа. ссылками можно написать функцию ргег)есеазог!). ана- во считается сбатансированным. В следующем разделе 32 вегасе аая1 воде 11ак!2); !.
Лагггн. Этот этап аналогичен первом) этапу при логичную функции зцссехяог!), но для дерева с правы- будет сначала рассмотрено АНЕ-дерево, а затем дерево 33 1ае Дага; вставке узла а обычное двоичное дерево поиска. ми ссылками нельзя написать такую эффективную фун- гег)-Ыасй.
Для каждого из этих типов сбалансированно- 34 вЬосе Ьа1; Кроме того, при продвижении вглубь дсрсаа трсбукцию. Преимуществом двоичного дерева с правыми го дерева мы укажем критерии проведения балансиров- 35 ); ется отслеживать дополнительную информацию. ссылкал<и является то, что операции изменения дерева ки, определим структуры их узлов и напишем функции 2. Всгнаана. Вставляем а дерево новый узсл будут проводиться быстрее, чем для дерева с полными для вставки и удаления узлов. Хотя коды функций для В эту структуру внесено несколько изменений по 3.
Пергс нега назг)н)гиг)ггентаа гбааансираттнасии Коэфссылками, поскольку нет нсобхолимости следить за выполнения других операций и не приводятся в книге, сравнению со структурами узлов, которые использовафициснты сбалансированности узлов. находяшихлеаыми ссылками. они вкчючсны в файлы агйс и гЬ.с на %сЬ-сайгте изда лись ранее. Давайте более подробно рассмотрим эти ся выше ново~о узла, изменились.
Заменяем ил но- Двоичное дерево со ссылками может занимать не- тсльства "ДиаСофт". изменения. Раньше у нас были связи 1ей и г)йЫ, теперь выми значениями. сколько л~еньший объем памяти, чем дерево с указатс- В последующих разделах рассмотрены вопросы в стр) ктуру узла ат) поде введен массив 1)пй, состояшии лами на родительские узлы. Оба этих подхода предло- вставки и удаления узлов в сбалансированном дереве, но из дан л указателей. 1)в)г!0) соответствует указателю!ей, 4. Рщнанин.
Если вставка нового узла приводит к полагают решение одних и тех же задач при прохождении со сбачансированнылг деревом лучше всего работать с а 1)вй)1) — указателю г!ВЬ). Это позволяет упростить сбалансированности дерева, то,тля поддержания дерева и оба требуют большего времени для выполне- помощью карандаша и бумаги. Попытайтесь нарисовать хранение ссылок на один из дочерних у шов ланного узза— оба.щнсированности нужно перенести неко гарме ния вставок и удачении узлов, чем в случае обычного дерево, затем вставить в него или удалить узел. После можно просто хранить О или 1 и использовать эти зна- С и а) Органа>он««н даном« ° ° « Паин, по анни«ион> дортш Часть й « Глава 12 130 ) 193 х- Ьа) = 01 131 е1не ( коэффициентов сбазансированности для узлов, находя- опрсдсляются значсния коэффициснтов сбалансирован- 132 х->Ьа1 = +1; 195 ) шихся мс;кду х и у.
Коэффициенты сбалансированнос- ности после выполнения двойной ротации. Болсс под- 133 х = х->11пх[1]1 ти висл этих узлов перед выполненисл«функции были робно эти подслучаи можно рассмотрсть по коду (стро- ) 197 равны нулю, поскольку х указывает на узел с нснулс- ки 152 †1). 135 вым коэффициентом сбалансированности, который бли- Послс проведения балансировки выполнсние функ- И <Иея а х->дата) Начинасл«с обьявлсния нсскольких псрсмснных и же всего находится к у по дереву от корня.
И всс эти ции завершается (строка 196). о ра отки особого случая вставки в пустос АНЕ-дерево 138 х->Ьа1-; т к 4 102 Л б б коэффицисн'ы сб 'ансиРованности пошзе выполнсниЯ (строки 94 — 102). Легче обработать этот особьш случаи и ч 139 е1ае И (я->Ьа1 == -1) ( опсрации булут отличными от нуля, поскольку при 140 отдсльно, а нс пытаться включить сго в общий алгоритм. х «и 'ч = н; вставкс у увеличивастся высота дерева.
-г 0 141 х->Ипх(0) = и->Ипк[11; Функция печи поде() являстся вспомогательной фун- После псрссчста коэффициентов сбалансированно- 142 и->11пх[1] = х; кциси, которая выделяет память под структуру ач! цобе. х-> а = и->Ьа = Ог Е и сли она завершастся успсшно, она инициализируст сти узлов, находящихся мсжду х и у, необходилю изл«с- -1 С л О 144 ) .. ' РУ нить коэффициент сбалансированности салюго узла х.