Главная страница Случайная страница Разделы сайта АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника |
💸 Как сделать бизнес проще, а карман толще?
Тот, кто работает в сфере услуг, знает — без ведения записи клиентов никуда. Мало того, что нужно видеть свое раписание, но и напоминать клиентам о визитах тоже.
Проблема в том, что средняя цена по рынку за такой сервис — 800 руб/мес или почти 15 000 руб за год. И это минимальный функционал.
Нашли самый бюджетный и оптимальный вариант: сервис VisitTime.⚡️ Для новых пользователей первый месяц бесплатно. А далее 290 руб/мес, это в 3 раза дешевле аналогов. За эту цену доступен весь функционал: напоминание о визитах, чаевые, предоплаты, общение с клиентами, переносы записей и так далее. ✅ Уйма гибких настроек, которые помогут вам зарабатывать больше и забыть про чувство «что-то мне нужно было сделать». Сомневаетесь? нажмите на текст, запустите чат-бота и убедитесь во всем сами! While not Eof(f) do begin
Read(f, Key); if Eoln(f) then ReadLn(f); Search(Key); // функция Search вызывается как процедура end; end; //procedure tSearchTree.Build 11. Сбалансированные деревья Поиск по дереву является эффективным только в том случае, если дерево будет идеально сбалансированным, так как среднее число сравнений, необходимых для обнаружения ключа, в идеально сбалансированном дереве равно log2 n. Если дерево вырождается в список, то эта величина примерно равна n /2. Анализ показывает, что процедура балансировки, восстанавливающая после каждого случайного включения идеально сбалансированное дерево, не всегда является выгодной, так как реализуется довольно сложно. Возможным выходом из положения является введение менее строгого понятия сбалансированности. Это может привести к более простой процедуре балансировки за счет незначительного увеличения времени поиска. Одно из таких определений сбалансированного дерева было предложено Г.М. Адельсон-Вельским и Е.М. Ландисом. Их критерий сбалансированности сформулирован следующим образом. Дерево называется сбалансированным, если высоты двух поддеревьев каждого из его узлов отличаются не более чем на единицу. Деревья, удовлетворяющие такому условию, часто называют АВЛ-деревьями (по имени их открывателей). Мы их будем называть сбалансированными деревьями. В таких деревьях, как доказали их авторы, операция поиска выполняется за время, пропорциональное log2 n. 12. Включение в сбалансированное дерево Есть корень r, левое (L) и правое (R) поддеревья с высотами hL и hR соответственно. Что может произойти при включении в сбалансированное дерево нового узла? Предположим, включение в L нового узла приведет к увеличению на 1 его высоты; тогда возможны три ситуации: 1) hL = hR: после включения L и R станут разной высоты, но критерий сбалансированности не будет нарушен; 2) hL < hR: после включения L и R станут равной высоты, т.е. сбалансированность улучшится; 3) hL > hR: после включения критерий сбалансированности нарушится и дерево необходимо перестраивать. Например, в сбалансированное дерево, приведенное ниже, узлы с ключами 9 и 11 можно включить, не нарушая его сбалансированности. Включение узлов 1, 3, 5 или 7 потребует последующей балансировки. Существуют лишь 2 различные возможности устранения несбалансированности, возникшей из-за включения, требующие индивидуального подхода (оставшиеся могут быть выведены из них на основе симметрии). Эти случаи показаны ниже. Прямоугольниками обозначены поддеревья, причем «добавленная» при включении высота заштрихована. Первый случай возникает, когда в дерево на числовом примере включаются узлы с ключами 1 или 3. Ситуация, характерная для второго случая, возникает при включении узлов с ключами 5 или 7. Простые преобразования восстанавливают желанную сбалансированность. Заметим, что допускаются лишь вертикальные перемещения, относительное горизонтальное расположение узлов и поддеревьев должно оставаться без изменения. Результат балансировки показан ниже. Алгоритм включения и балансировки существенно зависит от того, каким образом хранится информация о сбалансированности дерева. Удобно хранить в каждом узле показатель сбалансированности как разность между высотами правого и левого поддеревьев этого узла: Type TBalance= -1..+1; // тип показателя сбалансированности tItem = record // тип элемента дерева Value: tValue; // содержательная часть элемента дерева Left, Right: pItem; // указатели на левое и правое поддеревья Bal: TBalance; // показатель сбалансированности - разность между // высотами правого и левого поддеревьев узла end; // tItem Процесс включения узла в сбалансированное дерево состоит из трех последовательно выполняемых частей. 1. Проход по пути поиска, пока не убедимся, что ключа нет. 2. Включение нового узла и определение результирующего показателя сбалансированности. 3. «Отступления» по пути поиска и проверка в каждом узле показателя сбалансированности. Если необходимо – балансировка. Хотя при таком методе и требуются некоторые избыточные проверки (если сбалансированность уже зафиксирована, то нет необходимости проверять её в вышестоящих узлах), мы воспользуемся этой схемой, так как её можно реализовать расширением функции поиска с включением. Дополнительная информация, которую нужно передавать на каждом шаге, – изменение высоты поддерева в том месте, где произошло включение. Её можно передавать в виде булевской переменной H, означающей «высота дерева увеличилась». Рассмотрим процесс возвращения к узлу Item после включения в его левое поддерево, причем известно, что высота Item увеличилась. В зависимости от высоты поддеревьев перед включением мы должны различать три возможные ситуации: 1) hL < hR, Item ^. Bal = +1, предыдущая несбалансированность в Item уравновешивается; 2) hL = hR, Item^.Bal = 0, левое поддерево стало «перевешивать», но балансировка не нужна; 3) hL > hR, Item^.Bal = –1, необходима балансировка; В третьей ситуации по показателю сбалансированности корня p 1 левого поддерева можно определить, с каким из случаев балансировки мы имеем дело. Если p1^.Bal = –1 (левое поддерево этого узла также выше правого), то имеем дело со случаем 1, иначе – со случаем 2. Операция балансировки состоит только из последовательных переприсваиваний ссылок. Фактически ссылки циклически меняются местами, что приводит к однократному или двукратному повороту двух или трех участвующих в процессе узлов. Кроме вращения ссылок нужно должным образом поправить и показатели сбалансированности соответствующих узлов. Случай 1 называется однократным LL -поворотом (в левом дереве выросло левое поддерево): Для реализации LL -поворота необходимо выполнить однократный поворот двух узлов Item и p 1: Item^.Left: =p1^.Right; p1^.Right: =Item; Item: =p1; Случай 2 называется двойным LR -поворотом (в левом дереве выросло правое поддерево): Для реализации LR -поворота необходимо выполнить двукратный поворот трех узлов p1, p2 и Item: p1^.Right: =p2^.Left; p2^.Left: =p1; Item^.Left: =p2^.Right; p2^.Right: =Item; Item: =p2; Процедура, выполняющая все необходимые действия по балансировке, если высота левого поддерева узла Item увеличилась (Н=True), имеет вид: procedure LeftBalance(var Item: pItem; var H: Boolean); // Высота левого поддерева узла Item увеличилась, входное значение Н=True Var p1, p2: pItem; Begin
|