mirror of
https://github.com/krahets/hello-algo.git
synced 2026-07-05 20:24:19 +00:00
build
This commit is contained in:
@@ -4,7 +4,7 @@ comments: true
|
||||
|
||||
# 4.1 Массив
|
||||
|
||||
<u>Массив (array)</u> - это линейная структура данных, которая хранит элементы одного типа в непрерывной области памяти. Положение элемента в массиве называется его <u>индексом (index)</u>. На рисунке 4-1 показаны основные понятия, связанные с массивом, и способ его хранения.
|
||||
<u>Массив (array)</u> - это линейная структура данных, в которой элементы одного типа хранятся в непрерывной области памяти. Положение элемента в массиве называется его <u>индексом (index)</u>. На рисунке 4-1 показаны основные понятия, связанные с массивом, и способ его хранения.
|
||||
|
||||
{ class="animation-figure" }
|
||||
|
||||
@@ -14,7 +14,7 @@ comments: true
|
||||
|
||||
### 1. Инициализация массива
|
||||
|
||||
В зависимости от задачи мы можем выбрать один из двух способов инициализации массива: без начальных значений или с заданными начальными значениями. Если начальные значения не указаны, большинство языков программирования инициализируют элементы массива значением $0$ :
|
||||
Существует два способа инициализации массива: без начальных значений и с заданными начальными значениями. Если начальные значения не указаны, большинство языков программирования инициализируют элементы массива нулями:
|
||||
|
||||
=== "Python"
|
||||
|
||||
@@ -138,13 +138,13 @@ comments: true
|
||||
|
||||
### 2. Доступ к элементам
|
||||
|
||||
Элементы массива хранятся в непрерывной области памяти, а это означает, что вычислить адрес любого элемента очень просто. Зная адрес массива в памяти (то есть адрес первого элемента) и индекс некоторого элемента, мы можем по формуле с рисунка ниже вычислить адрес этого элемента и напрямую обратиться к нему.
|
||||
Элементы массива хранятся в непрерывной области памяти, что упрощает вычисление их адресов. Зная адрес массива в памяти (то есть адрес первого элемента) и индекс некоторого элемента, мы можем по формуле с рисунка ниже вычислить адрес этого элемента и напрямую обратиться к нему.
|
||||
|
||||
{ class="animation-figure" }
|
||||
|
||||
<p align="center"> Рисунок 4-2 Вычисление адреса элемента массива </p>
|
||||
|
||||
Если посмотреть на рисунок 4-2, можно заметить, что индекс первого элемента массива равен $0$ , и это кажется не слишком интуитивным, ведь естественнее было бы начинать счет с $1$ . Однако с точки зрения формулы адресации **индекс по сути является смещением относительно адреса памяти**. Смещение первого элемента равно $0$ , поэтому индекс $0$ вполне логичен.
|
||||
Если посмотреть на рисунок 4-2, можно заметить, что индекс первого элемента массива равен $0$ , и это кажется не слишком интуитивным, ведь естественнее было бы начинать счет с $1$ . Однако с точки зрения формулы адресации **индекс по сути является смещением относительно адреса памяти**. Смещение первого элемента равно $0$ , поэтому индекс $0$ полностью логичен.
|
||||
|
||||
Доступ к элементам массива очень эффективен: любой элемент массива можно получить за $O(1)$ времени.
|
||||
|
||||
@@ -324,13 +324,13 @@ comments: true
|
||||
|
||||
### 3. Вставка элемента
|
||||
|
||||
Элементы массива в памяти расположены "вплотную" друг к другу, и между ними нет места для размещения новых данных. Как показано на рисунке 4-3, если мы хотим вставить элемент в середину массива, то все элементы после этой позиции нужно сдвинуть на одну позицию вправо, а затем записать новое значение в освободившийся индекс.
|
||||
Элементы массива в памяти расположены вплотную друг к другу, и между ними нет места для размещения новых данных. Как показано на рисунке 4-3, если мы хотим вставить элемент в середину массива, то все элементы после этой позиции нужно сдвинуть на одну позицию вправо, а затем записать новое значение в освободившийся индекс.
|
||||
|
||||
{ class="animation-figure" }
|
||||
|
||||
<p align="center"> Рисунок 4-3 Пример вставки элемента в массив </p>
|
||||
|
||||
Стоит отметить, что длина массива фиксирована, поэтому вставка нового элемента неизбежно приведет к "потере" элемента на конце массива. Решение этой проблемы мы оставим для обсуждения в разделе о "списках".
|
||||
Стоит отметить, что длина массива фиксирована, поэтому вставка нового элемента неизбежно приведет к потере элемента на конце массива. Решение этой проблемы мы оставим для обсуждения в разделе о "списках".
|
||||
|
||||
=== "Python"
|
||||
|
||||
@@ -526,7 +526,7 @@ comments: true
|
||||
|
||||
<p align="center"> Рисунок 4-4 Пример удаления элемента из массива </p>
|
||||
|
||||
Обрати внимание: после удаления исходный последний элемент становится "бессмысленным", поэтому специально изменять его не требуется.
|
||||
Обрати внимание: после удаления исходный последний элемент становится бессмысленным, поэтому специально изменять его не требуется.
|
||||
|
||||
=== "Python"
|
||||
|
||||
@@ -692,7 +692,7 @@ comments: true
|
||||
|
||||
- **Высокая временная сложность**: средняя временная сложность и вставки, и удаления равна $O(n)$ , где $n$ - длина массива.
|
||||
- **Потеря элементов**: поскольку длина массива неизменяема, после вставки элементы, выходящие за пределы длины массива, будут потеряны.
|
||||
- **Потери памяти**: можно заранее инициализировать более длинный массив и использовать только его переднюю часть; тогда "теряемые" при вставке элементы на конце не будут нести смысла, но такой подход приводит к лишнему расходу памяти.
|
||||
- **Потери памяти**: можно заранее инициализировать более длинный массив и использовать только его переднюю часть; тогда теряемые при вставке элементы на конце не будут нести смысла, но такой подход приводит к лишнему расходу памяти.
|
||||
|
||||
### 5. Обход массива
|
||||
|
||||
@@ -939,7 +939,7 @@ comments: true
|
||||
|
||||
Чтобы найти заданный элемент в массиве, нужно пройти по массиву и на каждой итерации проверять, совпадает ли значение; если совпадает, вернуть соответствующий индекс.
|
||||
|
||||
Поскольку массив - это линейная структура данных, такая операция поиска называется "линейным поиском".
|
||||
Поскольку массив - это линейная структура данных, такая операция поиска называется линейным поиском.
|
||||
|
||||
=== "Python"
|
||||
|
||||
@@ -1326,8 +1326,8 @@ comments: true
|
||||
|
||||
```ruby title="array.rb"
|
||||
### Увеличить длину массива ###
|
||||
# Обратите внимание: Array в Ruby является динамическим массивом и может быть расширен напрямую
|
||||
# Для удобства обучения эта функция рассматривает Array как массив неизменяемой длины
|
||||
# Обратите внимание: Array в Ruby является динамическим массивом и может расширяться напрямую
|
||||
# Для удобства обучения в этой функции Array рассматривается как массив неизменяемой длины
|
||||
def extend(nums, enlarge)
|
||||
# Инициализировать массив увеличенной длины
|
||||
res = Array.new(nums.length + enlarge, 0)
|
||||
@@ -1349,13 +1349,13 @@ comments: true
|
||||
|
||||
## 4.1.2 Преимущества и ограничения массива
|
||||
|
||||
Массив хранится в непрерывной области памяти, и все его элементы имеют один и тот же тип. Такой подход содержит много априорной информации, которую система может использовать для оптимизации эффективности операций со структурой данных.
|
||||
Массив хранится в непрерывной области памяти, и все его элементы имеют один и тот же тип. Такой подход содержит богатую априорную информацию, которую система может использовать для оптимизации эффективности операций с этой структурой данных.
|
||||
|
||||
- **Высокая пространственная эффективность**: массив выделяет для данных непрерывный блок памяти без дополнительного структурного накладного расхода.
|
||||
- **Поддержка произвольного доступа**: массив позволяет обращаться к любому элементу за $O(1)$ времени.
|
||||
- **Локальность кэша**: при обращении к элементу массива компьютер загружает не только сам элемент, но и соседние данные, что позволяет использовать кэш для ускорения последующих операций.
|
||||
|
||||
Хранение в непрерывной области памяти - палка о двух концах, и у него есть следующие ограничения.
|
||||
Непрерывное хранение данных - это палка о двух концах, и у него есть следующие ограничения.
|
||||
|
||||
- **Низкая эффективность вставки и удаления**: когда элементов в массиве много, вставка и удаление требуют сдвига большого количества элементов.
|
||||
- **Неизменяемая длина**: после инициализации длина массива фиксирована; расширение массива требует копирования всех данных в новый массив, что стоит дорого.
|
||||
@@ -1366,7 +1366,7 @@ comments: true
|
||||
Массив - это базовая и очень распространенная структура данных. Он часто используется как в различных алгоритмах, так и при реализации более сложных структур данных.
|
||||
|
||||
- **Произвольный доступ**: если мы хотим случайным образом выбирать некоторые образцы, можно сохранить их в массиве и сгенерировать случайную последовательность индексов для выборки.
|
||||
- **Сортировка и поиск**: массив - самая распространенная структура данных для алгоритмов сортировки и поиска. Быстрая сортировка, сортировка слиянием, бинарный поиск и многие другие алгоритмы в основном работают именно с массивами.
|
||||
- **Таблица поиска**: когда нужно быстро находить элемент или его соответствие, массив можно использовать как lookup table. Например, если мы хотим реализовать отображение символов в коды ASCII, можно использовать значение ASCII как индекс, а соответствующий элемент хранить по этой позиции массива.
|
||||
- **Сортировка и поиск**: массив - самая распространенная структура данных для алгоритмов сортировки и поиска. Быстрая сортировка, сортировка слиянием, двоичный поиск и многие другие алгоритмы в основном работают именно с массивами.
|
||||
- **Таблица поиска**: когда нужно быстро находить элемент или его соответствие, массив можно использовать как таблицу поиска. Например, если мы хотим реализовать отображение символов в коды ASCII, можно использовать значение ASCII как индекс, а соответствующий элемент хранить по этой позиции массива.
|
||||
- **Машинное обучение**: в нейронных сетях широко используются операции линейной алгебры над векторами, матрицами и тензорами, и все эти данные строятся в форме массивов. Массив - самая часто используемая структура данных в программировании нейросетей.
|
||||
- **Реализация структур данных**: массивы можно использовать для реализации стеков, очередей, хеш-таблиц, куч, графов и других структур данных. Например, матрица смежности графа по сути является двумерным массивом.
|
||||
|
||||
Reference in New Issue
Block a user