- •Основные понятия структур
- •Концепция типа данных, простейшие типы данных, стандартные типы данных, органические типы (диапазоны)
- •Статические и полустатические структуры данных
- •2. 1. Массив.
- •2. 2. Запись, записи с вариантами.
- •2. 3. Стек.
- •5. Очередь
- •3.1. Односвязные списки, кольцевой список
- •2. 7. Отображение
- •Динамические структуры данных
- •3. 2. Двусвязный список, кольцевой двусвязный список
- •4. Рекурсивные алгоритмы
- •4. 1. Деревья, бинарные деревья, представление деревьев
- •4. 2. Основные операторы, используемые для работы с деревьями
- •4. 3. Алгоритм создания дерева бинарного поиска
- •4. 4. Прохождение бинарных деревьев
- •1. Прохождение в прямом порядке
- •3. Прохождение в обратном порядке
- •4. 5. Когда рекурсию использовать не нужно
- •4. 6. Рекурсивные программы, примеры
- •5. Поиск
- •5. 1. Линейный поиск
- •5. 2. Двоичный поиск
- •5. 3. Индексно-последовательный поиск
- •5. 3. Поиск в таблице
- •5. 4. Поиск прямой строки
- •Поиск по бинарному дереву
- •Алгоритм кнута, Морриса и Пратта
- •5. 6. Алгоритм Боуера и Мура
- •Сортировка. Необходимые определения и классификация сортировок. Сортировки прямого включения и выбора. Их эффективность Необходимые определения и классификация сортировок.
- •Сортировка методом прямого включения
- •Эффективность алгоритма сортировки прямого включения
- •Сортировка методом прямого выбора
- •Эффективность алгоритма сортировки прямого выбора
- •Сортировка прямого обмена. Её эффективность
- •Эффективность алгоритма сортировки прямого обмена
- •Улучшенные методы сортировки. Быстрая сортировка. Её эффективность.
- •Быстрая сортировка
- •Принцип работы быстрой сортировки
- •Пример работы быстрой сортировки
- •Блок-схема быстрой сортировки
- •Улучшенные методы сортировки. Сортировка шелла. Её эффективность. Сортировка шелла
- •Принцип работы сортировки шелла и необходимые расчёты для её реализации
- •Пример расчёта последовательности расстояний для малых массивов
- •Пример работы сортировки шелла
- •Принцип работы пирамидальной сортировки
- •Пример работы пирамидальной сортировки
- •Представление графов
- •Нахождение кратчайших путей между парами вершин
5. 3. Поиск в таблице
Поиск в массиве иногда называют поиском в таблице, особенно если ключ является составным объектом, таким как массив чисел или символов.
Массивы символов называют строками или словами.
Строковый тип определяется следующим образом:
Siring = ARRAY[0..M-1] OF CHAR;
Соответственно определяется и отношение порядка для строк:
(x=y)=(Aj:0≤j<M:xj=y,),
(x<y) = Ei:0≤i<N:((Aj:0≤j<i:хj = yj)&(хi<yi)).
Чтобы установить факт совпадения, нужно убедиться, что все символы сравниваемых строк соответственно равны один другому.
Поэтому сравнение составных операндов сводится к поиску их несовпадающих частей, т. е. к поиску "на неравенство".
Если неравных частей не существует, то можно говорить о равенстве.
Например: размер слов достаточно мал, меньше 30. В этом случае будет использоваться линейный поиск.
Для практических приложений желательно исходить из того, что строки имеют переменный размер, т.е размер указывается в каждой отдельной строке.
Размер не должен превосходить максимального размера М. Такая схема достаточно гибка, и подходит для многих случаев и она позволяет избежать сложностей динамического распределения памяти.
Чаще всего используются два таких представления размера строк:
Размер неявно указывается путем добавления концевого символа, и больше этот символ нигде не употребляется. Для этой цели используется "непечатаемый" символ со значением #0 - это минимальный символ из всего множества символов.
Размер явно хранится в качестве первого элемента массива, т. е. строка s имеет следующий вид: s = s0, s1, s2, …, sn-1, где
s1, s2, …, sn-1 - фактические символы строки,
s0 = CHR(N).
Преимущество этого приема в том, что размер доступен, недостаток - в том, что этот размер ограничен размером множества символов (256).
5. 4. Поиск прямой строки
Часто приходится сталкиваться со специфическим поиском, так называемым поиском строки. Его можно определить следующим образом. Пусть задан массив s из N элементов и массив р из М элементов, причем 0 < М < N. Описаны они так:
s: ARRAY[0..N-1] OF item; p: ARRAY[0..M-1] OF itemПоиск строки обнаруживает первое вхождение pes. Обычно i tern — это символы, т. е. s можно считать некоторым текстом, ар — образом или словом, и мы хотим найти первое вхождение этого слова в указанном тексте. Это действие типично для любых систем обработки текстов, отсюда и очевидная заинтересованность в поиске эффективного алгоритма для этой задачи. Однако прежде, чем обращать внимание на эффективность, давайте сначала разберем некий "прямолинейный" алгоритм поиска. Мы его будем называть прямым поиском строки.
Еще до определения алгоритма нужно более точно сформулировать, что же мы от него желаем получить. Будем считать результатом индекс г, указывающий на первое с начала строки совпадение с образом. С этой целью введем предикат Р (i,j):
P(iJ) = Ak: 0 <A</:si+t-p*. (147)
Наш результирующий индекс, очевидно, должен удовлетворять этому предикату P(i, М). Но этого недостаточно. Поскольку поиск должен обнаружить первое вхождение образа, P(k, M) должно быть ложным для всех k < i. Обозначим это условие через Q(i):
Q(i) = Ak:0<k<i: ~P(k, M). (1.48)
Поставленная задача сразу же наводит на мысль оформить поиск как повторяющееся сравнение, и мы предлагаем такой вариант:
i := -1;
REPEAT i := i+1 (« Q(i) .)
found : = P(i.M)
UNTIL found OR (i = N-M);
Вычисление Р, естественно, вновь сводится к повторяющимся сравнениям отдельных символов. Если применить к Р теорему Моргана, то получается, что итерации должны "искать" несовпадение между образом и строкой сим волов.
P(i,j)-<,Ak:0<k<j:sj+k-P*)~(-®i-0<k<j:Si+k*Pk)-
В результате этого уточнения мы приходим к повторению внутри повторения. Предикаты Ри Q включаются в соответствующие места программы как примечания. Они представляют собой инварианты циклов упомянутых итеративных процессов. i := -1, REPEAT
- L+1; j := 0; (-' 0(i) •) (1.49)
WHILE (] < M) and (S[i+j] = p[]]) DO (• P(i,j*1) •) j := 1+1;
(• Q(i) and P(i,j) and ((j = M) OR (s[i+j] <> p[j])) •) UNTIL (] = M) OR (i = N-M).
действительности член;' = Mb условии окончания соответству-т условию found, так как из него следует P(i, М). Член i = N - М мплицирует Q(N- M) и тем самым свидетельствует, что нигде в троке совпадения нет. Если итерации продолжаются при j < М, о они должны продолжаться и при S; >; ^ pj. В соответствии (1.4 7 ) отсюда следует - P(i,j), затем из-за (1.48) следует Q(j + 1), что и подтверждает справедливость Q(i) после очередного увели-ения;'.
Анализ прямого поиска в строке. Этот алгоритм работает достаточно эффективно, если мы допускаем, что несовпадение пары символов происходит по крайней мере после всего лишь нескольких сравнений во внутреннем цикле. При большой мощности типа item это достаточно частый случай. Можно предполагать, что для текстов, составленных из 128 символов, несовпадение будет обнаруживаться после одной или двух проверок. Тем не менее в худшем случае производительность будет внушать опасение. Возьмем, например, строку, состоящую из N - 1 символов А и единственного В, а образ содержит М - 1 символов А и опять В.
Чтобы обнаружить совпадение в конце строки, требуется произвести порядка N * М сравнений. К счастью, как мы скоро увидим, есть прием, который существенно улучшает обработку этого неблагоприятного варианта.
