* placeholder * 0413更新 * 0413删除comments * 第四章第一节进行一对一修改,发现几个核心问题,后续不再重复叙述。具体问题参见具体说明 因为该版本不会被用在最后的校对输出中,后续不再复制纸质版原文,只标注出现不一致的部分 1.非程序部分大量出现文本和纸质版不一致,已全部修改,AI翻译版本没有纸质版自然 2.程序部分python部分就和纸质版不一致,但是其他程序和AI翻译的python一致,建议让AI先搬运纸质版python的翻译,再加工其他的部分,翻译水平尚可。 3.程序部分AI翻译版本不稳定,大部分使用动宾结构表达,少部分使用动名词结构,出现少量语法错误。纸质版大多使用动名词结构 4.相对中文在线版格式未出现问题,该部分表现较好 * 第四章后续章节未精确修改和俄语版不一致的部分,因为从第一节可以看出,AI基本上都是自己翻的。 在这里标出了所有应该修改的部分 除了第一节以外新增的问题: 1.程序部分出现语法错误 2.单复数问题在程序和标题中出现多次,正文中更是屡见不鲜 3.程序部分,python错了之后,后续的程序全部参照python一起错,建议统一修改,还是参照python但是一起修改掉 * 第十章第一节整体检查 1.正文部分和纸质版的重叠仍然基本没有,都是AI翻译 2.程序部分除了python和纸质版翻译不一致以外,出现较为严重的术语错误 3.接下来的四节内容我将不再展示正文部分的不一致,以上已经可以充分说明了 * 第十章后续章节梳理(该部分仍然绝大部分的内容都和纸质版完全不一致,从措辞到表达方法都不一致,包括正文也包括程序) 考虑到还需要进行AI设计,在此没有重复标注 其他问题: 1.正文中有一些细节,比如说引号的删除、大小写的确认、 2.程序上也出现了术语错误和语法错误 * docs(ru): refine wording after sentence-level Chinese comparison --------- Co-authored-by: Veronica <[email protected]> Co-authored-by: krahets <[email protected]>
12 KiB
Переосмысление алгоритмов поиска
Алгоритмы поиска (searching algorithm) используются для того, чтобы находить один или несколько элементов, удовлетворяющих определенным условиям, в структурах данных, таких как массивы, списки, деревья или графы.
Алгоритмы поиска можно разделить на две категории по способу реализации.
- Поиск целевого элемента путем обхода структуры данных, например обход массива, списка, дерева или графа.
- Эффективный поиск элементов с использованием структуры организации данных или априорной информации, например двоичный поиск, хеш-поиск и поиск в двоичном дереве поиска.
Нетрудно заметить, что эти темы уже рассматривались в предыдущих главах, поэтому алгоритмы поиска нам уже знакомы. В этом разделе мы систематизируем полученные ранее знания и еще раз посмотрим на них как на единую группу методов.
Полный перебор
Полный перебор заключается в том, что мы обходим каждый элемент структуры данных, чтобы найти целевой элемент.
- Линейный поиск применяется к линейным структурам данных, таким как массивы и связные списки. Он начинается с одного конца структуры данных и последовательно проверяет элементы, пока не найдет целевой элемент или пока не достигнет другого конца структуры данных.
- Обход в ширину и обход в глубину - это две стратегии обхода графов и деревьев. Обход в ширину стартует из начального узла и исследует все узлы текущего уровня, прежде чем переходить к следующему. Обход в глубину стартует из начального узла, проходит один путь до конца, затем возвращается назад и пробует другие пути, пока не будет полностью пройдена вся структура данных.
Преимущество полного перебора состоит в его простоте и универсальности, поскольку он не требует предварительной обработки данных и использования дополнительных структур данных.
Однако временная сложность таких алгоритмов равна $O(n)$ , где n - число элементов, поэтому при больших объемах данных их производительность невысока.
Адаптивный поиск
Адаптивный поиск использует специфические свойства данных (например, упорядоченность), чтобы оптимизировать процесс поиска и тем самым эффективнее находить целевой элемент.
- Двоичный поиск использует упорядоченность данных для эффективного поиска и применим только к массивам.
- Хеш-поиск использует хеш-таблицу, связывая поисковые данные с целевыми данными в виде пар «ключ — значение», благодаря чему запросы выполняются эффективно.
- Поиск в дереве ведется в конкретной древовидной структуре (например, в двоичном дереве поиска) и позволяет быстро отсекать узлы на основе сравнения значений, чтобы найти цель.
Преимущество этих алгоритмов заключается в высокой эффективности: их временная сложность может достигать O(\log n) и даже $O(1)$ .
Однако для использования таких алгоритмов обычно требуется предварительная обработка данных. Например, для двоичного поиска нужно заранее отсортировать массив, а хеш-поиск и поиск в дереве требуют дополнительных структур данных, поддержание которых тоже отнимает время и память.
!!! tip
Адаптивные алгоритмы поиска часто называют алгоритмами поиска в узком смысле, **поскольку они в основном предназначены для быстрого нахождения целевого элемента в конкретной структуре данных**.
Выбор метода поиска
Для поиска целевого элемента в наборе данных размера n можно использовать линейный поиск, двоичный поиск, поиск в дереве, хеш-поиск и другие методы. Принципы работы этих методов показаны на рисунке ниже.
Эффективность и особенности перечисленных методов приведены в таблице ниже.
Таблица Сравнение эффективности алгоритмов поиска
| Линейный поиск | Двоичный поиск | Поиск в дереве | Хеш-поиск | |
|---|---|---|---|---|
| Поиск элемента | O(n) |
O(\log n) |
O(\log n) |
O(1) |
| Вставка элемента | O(1) |
O(n) |
O(\log n) |
O(1) |
| Удаление элемента | O(n) |
O(n) |
O(\log n) |
O(1) |
| Дополнительное пространство | O(1) |
O(1) |
O(n) |
O(n) |
| Предварительная обработка | / | Сортировка O(n \log n) |
Построение дерева O(n \log n) |
Построение хеш-таблицы O(n) |
| Упорядоченность данных | Не требуется | Требуется | Требуется | Не требуется |
Выбор алгоритма поиска также зависит от масштаба данных, требований к производительности поиска, а также частоты запросов и обновлений данных.
Линейный поиск
- Обладает хорошей универсальностью и не требует никакой предварительной обработки данных. Если нужно выполнить только один запрос, то время предварительной обработки для остальных трех методов окажется больше, чем время линейного поиска.
- Подходит для небольших объемов данных, потому что в этом случае влияние временной сложности на эффективность невелико.
- Подходит для сценариев с высокой частотой обновления данных, поскольку этот метод не требует никакого дополнительного обслуживания данных.
Двоичный поиск
- Подходит для больших наборов данных и демонстрирует стабильную эффективность. Его худшая временная сложность равна
O(\log n). - Объем данных не должен быть слишком большим, потому что массив требует непрерывного участка памяти.
- Не подходит для сценариев с частыми вставками и удалениями данных, так как поддержание массива в отсортированном виде требует больших затрат.
Хеш-поиск
- Подходит для сценариев, в которых требования к скорости запросов очень высоки. Средняя временная сложность равна
O(1). - Не подходит для сценариев, где требуется упорядоченность данных или поиск по диапазону, потому что хеш-таблица не умеет поддерживать порядок данных.
- Сильно зависит от хеш-функции и стратегии обработки коллизий, поэтому риск деградации производительности сравнительно велик.
- Не подходит для слишком больших объемов данных, так как хеш-таблице требуется дополнительное пространство, чтобы максимально снизить число коллизий и обеспечить хорошую производительность поиска.
Поиск в дереве
- Подходит для очень больших объемов данных, потому что узлы дерева распределены в памяти и не требуют непрерывного хранения.
- Подходит для сценариев, где нужно поддерживать упорядоченные данные или выполнять поиск по диапазону.
- В процессе постоянных вставок и удалений узлов двоичное дерево поиска может перекоситься, и тогда временная сложность деградирует до
O(n). - Если использовать AVL-дерево или красно-черное дерево, то все операции могут стабильно выполняться за
O(\log n), но поддержание баланса дерева увеличивает дополнительные накладные расходы.
