TURBO PASCAL |
Новости
|
ПоискЦель: поиск в массиве, поиск по дереву. Одной из нескольких наиболее фундаментальных операций, присущей огромному количеству вычислительных задач, является поиск. Поиск - нахождение какой-либо конкретной информации в большом объеме ранее собранных данных. Данные делятся на записи, и каждая запись имеет хотя бы один ключ. Ключ используется для того, чтобы отличить одну запись от другой. Целью поиска является нахождение всех записей подходящих к заданному ключу поиска. Вначале рассмотрим поиск с позиций пользователя. Кроме поиска совпадению аргумента поиска с ключом записи, существует поиск по близости аргумента и ключа и поиск по интервалу, означающий попадание ключа в заданный двумя аргументами (границами) интервал. В последнем случае результат - множество записей, хотя бы и пустое. При поиске по совпадению - также. Те же принципы (условия) поиска применимы и к преобразованным ключам - значениям некоторой функции содержания записи. Указанные выше условия поиска будем считать элементарными. Логически сложные условия поиска могут быть конъюнктивными (обязательно выполнение в искомых записях всех заданных элементарны условий), дизъюнктивными (достаточно выполнения одного из них) смешанной природы. Рассмотренный выше поиск назовем ординарным, ибо возможно толкование тех же условий на более сложном, так называемом семантическом плане. Пример: найти, среди многих, реферат статьи, наиболее близкий к указанной теме. Итак, возможна следующая классификация случаев поиска: Для поиска по совпадению можно было бы отделить случай поиска единственной записи от случая поиска многих записей. Эту классификацию не следует путать с классификацией средств поиска. Любой случай может быть реализован как простой перебор записей (медленный поиск) и как бинарный (быстрый) поиск. Для удобства программирования будем искать в массиве запись, ближайшую снизу к левой границе и не равную ей, и запись, ближайшую сверху к правой границе и не равную ей. Эти записи в ответ не входят. Если найденные записи являются соседними, результатом оказывается пустое множество записей. Рассмотрим простой перебор записей. Его можно реализовать с помощью следующего алгоритма. function search(x: integer): integer; Реализуем более сложный алгоритм поиска. Этот алгоритм называется бинарный поиск(дихотомия). Смысл этого алгоритма в отсортированном массиве ищем середину, если искомый элемент меньше серединного элемента, то ищем в левой части, а если больше, то в правой. У найденного интервала снова ищем середину и опять сравниваем искомый элемент и т.д. Type fun= function (j:word):Boolean; Параметром L мы задаем случай поиска: L = -1 (L = 1) при поиске по близости снизу (сверху); L = 2 при поиске по совпадению (одна запись); L = 3 при поиске по совпадению (все записи) или по интервалу. При L = 3 и usp = 1 (поиск успешен) найденные номера m (меньший), k (больший) обозначают позиции, непосредственно примыкающие к позициям группы искомых записей, а в остальных случаях, когда usp = 1 ("успех"), номером найденной записи является m. Аргумент поиска явно не показан, а скрыт в записываемых пользователем логических функциях f1, f2 с единственным параметром - номером j записи. В fl (f2) записывается, что f1 (f2) истинна, когда ключ записи меньше (больше) аргумента. Параметры m, k - это не только результирующие номера записей, но и (в момент обращения) внешние границы исходной области поиска. Для увеличения эффективности поиска в отсортированном файле существует другой метод, но он приводит к увеличению требуемого пространства. Этот метод называется индексно - последовательным методом поиска. В дополнение к отсортированному файлу заводится некоторая вспомогательная таблица, называемая индексом. Каждый элемент индекса состоит из ключа kindex и указателя на запись в файле, соответствующую этому ключу kindex. Элементы в индексе, так же как и элементы в файле, должны быть отсортированы по этому ключу. Если индекс имеет размер, составляющий одну восьмую от размера файла, то каждая восьмая запись в файле представлена первоначально в индексе. Это показано на рисунке. Поиск в Бинарном Дереве Поиск в бинарном дереве является простым и эффективным методом, который считается одним из наиболее фундаментальных в компьютерной науке. Он чрезвычайно легок в использовании, но на самом деле он довольно широко используется во многих ситуациях. Рассмотрим следующее БДУ Поиск по совпадению является самым легким идем влево, если искомая запись меньше ключа в узле и вправо, если больше либо равна. Больший интерес вызывают случаи, когда идет поиск по близости и поиск по интервалу. Рассмотрим поиск по близости. При обходе дерева указатели на узлы этого дерева по пути поиска будем заносить в стек. При аргументе поиска 20 мы останавливаемся на 21 и прекращаем поиск. Затем смотрим на вершину стека и там находится ближайшее число к 20. При поиске по интервалу находим левую границу или максимально к ней приближенную, а затем просматриваем стек в обратном порядке(или если нужно дерево) ищем правую границу, т.е. ищем все узлы, которые больше либо равны левой границе, но меньше правой. Параметры сог - ссылка на корень БДУ, arl, ar2 - аргументы поиска (значение аг2 задают лишь для поиска по интервалу как правую его границу, но параметр этот записывают всегда), L - вариант поиска (при поиске по интервалу L=4), рр - признак успешности Procedure Obrab(ss:pt); {Obrab -
процедура-"заглушка",
} Бинарное дерево является частным случаем B-дерева. В-деревом порядка m такое дерево определяется как некоторое общее дерево, которое удовлетворяет следующим условиям:
На рис. показано некоторое В-дерево порядка 5. Отметим, что каждый узел может быть .представлен как некоторый упорядоченный набор(p1, k1, p2, k2, ..., kn-1, рn) где pi является указателем (возможно, пустым, если данный узел является листом), а ki является некоторым ключом. Все ключи в узле, на которые указывает pi, находятся между ki-1 и ki, а внутри каждого узла выполняется неравенство k1<k2<.. .<kn-1. Дерево 2-3-4 тоже является частным случаем B-дерева. B-деревья очень эффективны при поиске. Деревья цифрового поиска Другой метод использования деревьев для ускорения поиска состоит в формировании некоторого общего дерева, основанного на символах, из которых состоят ключи. Например, если ключи являются числовыми, то каждая позиция цифры определяет одного из 10 возможных сыновей заданного узла. Каждый узел, являющийся листом дерева, содержит специальный символ eok, который представляет конец некоторого ключа. Такой узел, являющийся листом, должен также содержать некоторый указатель на запись, которая запоминается. Однако данное дерево можно сделать даже еще меньше, исключив те узлы, из которых можно достичь только одиночных листьев. Штриховая линия используется для представления указателя от узла дерева на ключ. Итак, на сегодняшнем занятии мы рассмотрели основные алгоритмы поиска. |
(с)Все права защищены По всем интересующим вопросам прошу писать на электронный адрес |