Files
hello-algo/ru/docs/chapter_array_and_linkedlist/list.md
2026-03-30 07:27:40 +08:00

37 KiB
Raw Blame History

Список

Список (list) - это абстрактное понятие структуры данных, обозначающее упорядоченную коллекцию элементов, которая поддерживает доступ к элементам, их изменение, добавление, удаление и обход, не требуя от пользователя учитывать ограничения по емкости. Список может быть реализован как на основе связного списка, так и на основе массива.

  • Связный список естественным образом можно рассматривать как список: он поддерживает операции добавления, удаления, поиска и изменения элементов и может гибко расширяться динамически.
  • Массив тоже поддерживает операции добавления, удаления, поиска и изменения элементов, но из-за неизменяемости длины его можно считать лишь списком с ограниченной длиной.

Когда список реализуется с помощью массива, неизменяемость длины снижает его практическую полезность. Причина в том, что мы обычно не можем заранее точно знать, сколько данных нужно хранить, а значит, трудно выбрать подходящую длину списка. Если длина слишком мала, она может не покрыть реальные потребности; если слишком велика, будет зря расходоваться память.

Чтобы решить эту проблему, можно использовать динамический массив (dynamic array) для реализации списка. Он сохраняет все преимущества массива и при этом может динамически расширяться во время выполнения программы.

На практике списки из стандартных библиотек многих языков программирования реализованы именно на основе динамических массивов, например list в Python, ArrayList в Java, vector в C++ и List в C#. В дальнейшем обсуждении мы будем считать понятия "список" и "динамический массив" эквивалентными.

Основные операции со списком

Инициализация списка

Обычно используются два способа инициализации: без начальных значений и с начальными значениями:

=== "Python"

```python title="list.py"
# Инициализация списка
# Без начальных значений
nums1: list[int] = []
# С начальными значениями
nums: list[int] = [1, 3, 2, 5, 4]
```

=== "C++"

```cpp title="list.cpp"
/* Инициализация списка */
// Обрати внимание: в C++ vector соответствует описываемому здесь nums
// Без начальных значений
vector<int> nums1;
// С начальными значениями
vector<int> nums = { 1, 3, 2, 5, 4 };
```

=== "Java"

```java title="list.java"
/* Инициализация списка */
// Без начальных значений
List<Integer> nums1 = new ArrayList<>();
// С начальными значениями (обрати внимание: элементы массива должны использовать обертку Integer[] вместо int[])
Integer[] numbers = new Integer[] { 1, 3, 2, 5, 4 };
List<Integer> nums = new ArrayList<>(Arrays.asList(numbers));
```

=== "C#"

```csharp title="list.cs"
/* Инициализация списка */
// Без начальных значений
List<int> nums1 = [];
// С начальными значениями
int[] numbers = [1, 3, 2, 5, 4];
List<int> nums = [.. numbers];
```

=== "Go"

```go title="list_test.go"
/* Инициализация списка */
// Без начальных значений
nums1 := []int{}
// С начальными значениями
nums := []int{1, 3, 2, 5, 4}
```

=== "Swift"

```swift title="list.swift"
/* Инициализация списка */
// Без начальных значений
let nums1: [Int] = []
// С начальными значениями
var nums = [1, 3, 2, 5, 4]
```

=== "JS"

```javascript title="list.js"
/* Инициализация списка */
// Без начальных значений
const nums1 = [];
// С начальными значениями
const nums = [1, 3, 2, 5, 4];
```

=== "TS"

```typescript title="list.ts"
/* Инициализация списка */
// Без начальных значений
const nums1: number[] = [];
// С начальными значениями
const nums: number[] = [1, 3, 2, 5, 4];
```

=== "Dart"

```dart title="list.dart"
/* Инициализация списка */
// Без начальных значений
List<int> nums1 = [];
// С начальными значениями
List<int> nums = [1, 3, 2, 5, 4];
```

=== "Rust"

```rust title="list.rs"
/* Инициализация списка */
// Без начальных значений
let nums1: Vec<i32> = Vec::new();
// С начальными значениями
let nums: Vec<i32> = vec![1, 3, 2, 5, 4];
```

=== "C"

```c title="list.c"
// В C нет встроенного динамического массива
```

=== "Kotlin"

```kotlin title="list.kt"
/* Инициализация списка */
// Без начальных значений
var nums1 = listOf<Int>()
// С начальными значениями
var numbers = arrayOf(1, 3, 2, 5, 4)
var nums = numbers.toMutableList()
```

=== "Ruby"

```ruby title="list.rb"
# Инициализация списка
# Без начальных значений
nums1 = []
# С начальными значениями
nums = [1, 3, 2, 5, 4]
```

??? pythontutor "Визуализация выполнения"

https://pythontutor.com/render.html#code=%22%22%22Driver%20Code%22%22%22%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20%23%20%D0%98%D0%BD%D0%B8%D1%86%D0%B8%D0%B0%D0%BB%D0%B8%D0%B7%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D1%82%D1%8C%20%D1%81%D0%BF%D0%B8%D1%81%D0%BE%D0%BA%0A%20%20%20%20%23%20%D0%91%D0%B5%D0%B7%20%D0%BD%D0%B0%D1%87%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D1%85%20%D0%B7%D0%BD%D0%B0%D1%87%D0%B5%D0%BD%D0%B8%D0%B9%0A%20%20%20%20nums1%20%3D%20%5B%5D%0A%20%20%20%20%23%20%D0%A1%20%D0%BD%D0%B0%D1%87%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%BC%D0%B8%20%D0%B7%D0%BD%D0%B0%D1%87%D0%B5%D0%BD%D0%B8%D1%8F%D0%BC%D0%B8%0A%20%20%20%20nums%20%3D%20%5B1%2C%203%2C%202%2C%205%2C%204%5D&cumulative=false&curInstr=4&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=311&rawInputLstJSON=%5B%5D&textReferences=false

Доступ к элементам

Поскольку в этом разделе список рассматривается как структура на основе динамического массива, доступ к элементам и их обновление можно выполнять за O(1) времени, что очень эффективно.

=== "Python"

```python title="list.py"
# Доступ к элементу
num: int = nums[1]  # Доступ к элементу по индексу 1

# Обновление элемента
nums[1] = 0    # Обновить элемент по индексу 1 значением 0
```

=== "C++"

```cpp title="list.cpp"
/* Доступ к элементу */
int num = nums[1];  // Доступ к элементу по индексу 1

/* Обновление элемента */
nums[1] = 0;  // Обновить элемент по индексу 1 значением 0
```

=== "Java"

```java title="list.java"
/* Доступ к элементу */
int num = nums.get(1);  // Доступ к элементу по индексу 1

/* Обновление элемента */
nums.set(1, 0);  // Обновить элемент по индексу 1 значением 0
```

=== "C#"

```csharp title="list.cs"
/* Доступ к элементу */
int num = nums[1];  // Доступ к элементу по индексу 1

/* Обновление элемента */
nums[1] = 0;  // Обновить элемент по индексу 1 значением 0
```

=== "Go"

```go title="list_test.go"
/* Доступ к элементу */
num := nums[1]  // Доступ к элементу по индексу 1

/* Обновление элемента */
nums[1] = 0     // Обновить элемент по индексу 1 значением 0
```

=== "Swift"

```swift title="list.swift"
/* Доступ к элементу */
let num = nums[1] // Доступ к элементу по индексу 1

/* Обновление элемента */
nums[1] = 0 // Обновить элемент по индексу 1 значением 0
```

=== "JS"

```javascript title="list.js"
/* Доступ к элементу */
const num = nums[1];  // Доступ к элементу по индексу 1

/* Обновление элемента */
nums[1] = 0;  // Обновить элемент по индексу 1 значением 0
```

=== "TS"

```typescript title="list.ts"
/* Доступ к элементу */
const num: number = nums[1];  // Доступ к элементу по индексу 1

/* Обновление элемента */
nums[1] = 0;  // Обновить элемент по индексу 1 значением 0
```

=== "Dart"

```dart title="list.dart"
/* Доступ к элементу */
int num = nums[1];  // Доступ к элементу по индексу 1

/* Обновление элемента */
nums[1] = 0;  // Обновить элемент по индексу 1 значением 0
```

=== "Rust"

```rust title="list.rs"
/* Доступ к элементу */
let num: i32 = nums[1];  // Доступ к элементу по индексу 1
/* Обновление элемента */
nums[1] = 0;             // Обновить элемент по индексу 1 значением 0
```

=== "C"

```c title="list.c"
// В C нет встроенного динамического массива
```

=== "Kotlin"

```kotlin title="list.kt"
/* Доступ к элементу */
val num = nums[1]       // Доступ к элементу по индексу 1
/* Обновление элемента */
nums[1] = 0             // Обновить элемент по индексу 1 значением 0
```

=== "Ruby"

```ruby title="list.rb"
# Доступ к элементу
num = nums[1] # Доступ к элементу по индексу 1
# Обновление элемента
nums[1] = 0 # Обновить элемент по индексу 1 значением 0
```

??? pythontutor "Визуализация выполнения"

https://pythontutor.com/render.html#code=%22%22%22Driver%20Code%22%22%22%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20%23%20%D0%98%D0%BD%D0%B8%D1%86%D0%B8%D0%B0%D0%BB%D0%B8%D0%B7%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D1%82%D1%8C%20%D1%81%D0%BF%D0%B8%D1%81%D0%BE%D0%BA%0A%20%20%20%20nums%20%3D%20%5B1%2C%203%2C%202%2C%205%2C%204%5D%0A%0A%20%20%20%20%23%20%D0%9F%D0%BE%D0%BB%D1%83%D1%87%D0%B8%D1%82%D1%8C%20%D0%B4%D0%BE%D1%81%D1%82%D1%83%D0%BF%20%D0%BA%20%D1%8D%D0%BB%D0%B5%D0%BC%D0%B5%D0%BD%D1%82%D1%83%0A%20%20%20%20num%20%3D%20nums%5B1%5D%20%20%23%20%D0%BE%D0%B1%D1%80%D0%B0%D1%82%D0%B8%D1%82%D1%8C%D1%81%D1%8F%20%D0%BA%D0%B8%D0%BD%D0%B4%D0%B5%D0%BA%D1%81%201%20%D0%BF%D0%BE%D1%8D%D0%BB%D0%B5%D0%BC%D0%B5%D0%BD%D1%82%0A%0A%20%20%20%20%23%20%D0%9E%D0%B1%D0%BD%D0%BE%D0%B2%D0%B8%D1%82%D1%8C%20%D1%8D%D0%BB%D0%B5%D0%BC%D0%B5%D0%BD%D1%82%0A%20%20%20%20nums%5B1%5D%20%3D%200%20%20%20%20%23%20%D0%9E%D0%B1%D0%BD%D0%BE%D0%B2%D0%B8%D1%82%D1%8C%20%D1%8D%D0%BB%D0%B5%D0%BC%D0%B5%D0%BD%D1%82%20%D0%BF%D0%BE%20%D0%B8%D0%BD%D0%B4%D0%B5%D0%BA%D1%81%D1%83%201%20%D0%B4%D0%BE%200&cumulative=false&curInstr=3&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=311&rawInputLstJSON=%5B%5D&textReferences=false

Вставка и удаление элементов

В отличие от массива список позволяет свободно добавлять и удалять элементы. Добавление элемента в конец списка имеет временную сложность O(1) , но операции вставки и удаления по-прежнему имеют ту же эффективность, что и у массива, то есть O(n) .

=== "Python"

```python title="list.py"
# Очистить список
nums.clear()

# Добавить элементы в конец
nums.append(1)
nums.append(3)
nums.append(2)
nums.append(5)
nums.append(4)

# Вставить элемент в середину
nums.insert(3, 6)  # Вставить число 6 по индексу 3

# Удалить элемент
nums.pop(3)        # Удалить элемент по индексу 3
```

=== "C++"

```cpp title="list.cpp"
/* Очистить список */
nums.clear();

/* Добавить элементы в конец */
nums.push_back(1);
nums.push_back(3);
nums.push_back(2);
nums.push_back(5);
nums.push_back(4);

/* Вставить элемент в середину */
nums.insert(nums.begin() + 3, 6);  // Вставить число 6 по индексу 3

/* Удалить элемент */
nums.erase(nums.begin() + 3);      // Удалить элемент по индексу 3
```

=== "Java"

```java title="list.java"
/* Очистить список */
nums.clear();

/* Добавить элементы в конец */
nums.add(1);
nums.add(3);
nums.add(2);
nums.add(5);
nums.add(4);

/* Вставить элемент в середину */
nums.add(3, 6);  // Вставить число 6 по индексу 3

/* Удалить элемент */
nums.remove(3);  // Удалить элемент по индексу 3
```

=== "C#"

```csharp title="list.cs"
/* Очистить список */
nums.Clear();

/* Добавить элементы в конец */
nums.Add(1);
nums.Add(3);
nums.Add(2);
nums.Add(5);
nums.Add(4);

/* Вставить элемент в середину */
nums.Insert(3, 6);  // Вставить число 6 по индексу 3

/* Удалить элемент */
nums.RemoveAt(3);  // Удалить элемент по индексу 3
```

=== "Go"

```go title="list_test.go"
/* Очистить список */
nums = nil

/* Добавить элементы в конец */
nums = append(nums, 1)
nums = append(nums, 3)
nums = append(nums, 2)
nums = append(nums, 5)
nums = append(nums, 4)

/* Вставить элемент в середину */
nums = append(nums[:3], append([]int{6}, nums[3:]...)...) // Вставить число 6 по индексу 3

/* Удалить элемент */
nums = append(nums[:3], nums[4:]...) // Удалить элемент по индексу 3
```

=== "Swift"

```swift title="list.swift"
/* Очистить список */
nums.removeAll()

/* Добавить элементы в конец */
nums.append(1)
nums.append(3)
nums.append(2)
nums.append(5)
nums.append(4)

/* Вставить элемент в середину */
nums.insert(6, at: 3) // Вставить число 6 по индексу 3

/* Удалить элемент */
nums.remove(at: 3) // Удалить элемент по индексу 3
```

=== "JS"

```javascript title="list.js"
/* Очистить список */
nums.length = 0;

/* Добавить элементы в конец */
nums.push(1);
nums.push(3);
nums.push(2);
nums.push(5);
nums.push(4);

/* Вставить элемент в середину */
nums.splice(3, 0, 6); // Вставить число 6 по индексу 3

/* Удалить элемент */
nums.splice(3, 1);  // Удалить элемент по индексу 3
```

=== "TS"

```typescript title="list.ts"
/* Очистить список */
nums.length = 0;

/* Добавить элементы в конец */
nums.push(1);
nums.push(3);
nums.push(2);
nums.push(5);
nums.push(4);

/* Вставить элемент в середину */
nums.splice(3, 0, 6); // Вставить число 6 по индексу 3

/* Удалить элемент */
nums.splice(3, 1);  // Удалить элемент по индексу 3
```

=== "Dart"

```dart title="list.dart"
/* Очистить список */
nums.clear();

/* Добавить элементы в конец */
nums.add(1);
nums.add(3);
nums.add(2);
nums.add(5);
nums.add(4);

/* Вставить элемент в середину */
nums.insert(3, 6); // Вставить число 6 по индексу 3

/* Удалить элемент */
nums.removeAt(3); // Удалить элемент по индексу 3
```

=== "Rust"

```rust title="list.rs"
/* Очистить список */
nums.clear();

/* Добавить элементы в конец */
nums.push(1);
nums.push(3);
nums.push(2);
nums.push(5);
nums.push(4);

/* Вставить элемент в середину */
nums.insert(3, 6);  // Вставить число 6 по индексу 3

/* Удалить элемент */
nums.remove(3);    // Удалить элемент по индексу 3
```

=== "C"

```c title="list.c"
// В C нет встроенного динамического массива
```

=== "Kotlin"

```kotlin title="list.kt"
/* Очистить список */
nums.clear();

/* Добавить элементы в конец */
nums.add(1);
nums.add(3);
nums.add(2);
nums.add(5);
nums.add(4);

/* Вставить элемент в середину */
nums.add(3, 6);  // Вставить число 6 по индексу 3

/* Удалить элемент */
nums.remove(3);  // Удалить элемент по индексу 3
```

=== "Ruby"

```ruby title="list.rb"
# Очистить список
nums.clear

# Добавить элементы в конец
nums << 1
nums << 3
nums << 2
nums << 5
nums << 4

# Вставить элемент в середину
nums.insert(3, 6) # Вставить число 6 по индексу 3

# Удалить элемент
nums.delete_at(3) # Удалить элемент по индексу 3
```

??? pythontutor "Визуализация выполнения"

https://pythontutor.com/render.html#code=%22%22%22Driver%20Code%22%22%22%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20%23%20%D0%A1%20%D0%BD%D0%B0%D1%87%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%BC%D0%B8%20%D0%B7%D0%BD%D0%B0%D1%87%D0%B5%D0%BD%D0%B8%D1%8F%D0%BC%D0%B8%0A%20%20%20%20nums%20%3D%20%5B1%2C%203%2C%202%2C%205%2C%204%5D%0A%20%20%20%20%0A%20%20%20%20%23%20%D0%9E%D1%87%D0%B8%D1%81%D1%82%D0%B8%D1%82%D1%8C%20%D1%81%D0%BF%D0%B8%D1%81%D0%BE%D0%BA%0A%20%20%20%20nums.clear%28%29%0A%20%20%20%20%0A%20%20%20%20%23%20%D0%94%D0%BE%D0%B1%D0%B0%D0%B2%D0%B8%D1%82%D1%8C%20%D1%8D%D0%BB%D0%B5%D0%BC%D0%B5%D0%BD%D1%82%20%D0%B2%20%D0%BA%D0%BE%D0%BD%D0%B5%D1%86%0A%20%20%20%20nums.append%281%29%0A%20%20%20%20nums.append%283%29%0A%20%20%20%20nums.append%282%29%0A%20%20%20%20nums.append%285%29%0A%20%20%20%20nums.append%284%29%0A%20%20%20%20%0A%20%20%20%20%23%20%D0%92%D1%81%D1%82%D0%B0%D0%B2%D0%B8%D1%82%D1%8C%20%D1%8D%D0%BB%D0%B5%D0%BC%D0%B5%D0%BD%D1%82%20%D0%B2%20%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D1%83%0A%20%20%20%20nums.insert%283%2C%206%29%20%20%23%20%D0%92%D1%81%D1%82%D0%B0%D0%B2%D0%B8%D1%82%D1%8C%20%D1%87%D0%B8%D1%81%D0%BB%D0%BE%206%20%D0%BF%D0%BE%20%D0%B8%D0%BD%D0%B4%D0%B5%D0%BA%D1%81%D1%83%203%0A%20%20%20%20%0A%20%20%20%20%23%20%D0%A3%D0%B4%D0%B0%D0%BB%D0%B8%D1%82%D1%8C%20%D1%8D%D0%BB%D0%B5%D0%BC%D0%B5%D0%BD%D1%82%0A%20%20%20%20nums.pop%283%29%20%20%20%20%20%20%20%20%23%20%D0%A3%D0%B4%D0%B0%D0%BB%D0%B8%D1%82%D1%8C%20%D1%8D%D0%BB%D0%B5%D0%BC%D0%B5%D0%BD%D1%82%20%D0%BF%D0%BE%20%D0%B8%D0%BD%D0%B4%D0%B5%D0%BA%D1%81%D1%83%203&cumulative=false&curInstr=3&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=311&rawInputLstJSON=%5B%5D&textReferences=false

Обход списка

Как и массив, список можно обходить как по индексам, так и напрямую по элементам.

=== "Python"

```python title="list.py"
# Обход списка по индексам
count = 0
for i in range(len(nums)):
    count += nums[i]

# Прямой обход элементов списка
for num in nums:
    count += num
```

=== "C++"

```cpp title="list.cpp"
/* Обход списка по индексам */
int count = 0;
for (int i = 0; i < nums.size(); i++) {
    count += nums[i];
}

/* Прямой обход элементов списка */
count = 0;
for (int num : nums) {
    count += num;
}
```

=== "Java"

```java title="list.java"
/* Обход списка по индексам */
int count = 0;
for (int i = 0; i < nums.size(); i++) {
    count += nums.get(i);
}

/* Прямой обход элементов списка */
for (int num : nums) {
    count += num;
}
```

=== "C#"

```csharp title="list.cs"
/* Обход списка по индексам */
int count = 0;
for (int i = 0; i < nums.Count; i++) {
    count += nums[i];
}

/* Прямой обход элементов списка */
count = 0;
foreach (int num in nums) {
    count += num;
}
```

=== "Go"

```go title="list_test.go"
/* Обход списка по индексам */
count := 0
for i := 0; i < len(nums); i++ {
    count += nums[i]
}

/* Прямой обход элементов списка */
count = 0
for _, num := range nums {
    count += num
}
```

=== "Swift"

```swift title="list.swift"
/* Обход списка по индексам */
var count = 0
for i in nums.indices {
    count += nums[i]
}

/* Прямой обход элементов списка */
count = 0
for num in nums {
    count += num
}
```

=== "JS"

```javascript title="list.js"
/* Обход списка по индексам */
let count = 0;
for (let i = 0; i < nums.length; i++) {
    count += nums[i];
}

/* Прямой обход элементов списка */
count = 0;
for (const num of nums) {
    count += num;
}
```

=== "TS"

```typescript title="list.ts"
/* Обход списка по индексам */
let count = 0;
for (let i = 0; i < nums.length; i++) {
    count += nums[i];
}

/* Прямой обход элементов списка */
count = 0;
for (const num of nums) {
    count += num;
}
```

=== "Dart"

```dart title="list.dart"
/* Обход списка по индексам */
int count = 0;
for (var i = 0; i < nums.length; i++) {
    count += nums[i];
}

/* Прямой обход элементов списка */
count = 0;
for (var num in nums) {
    count += num;
}
```

=== "Rust"

```rust title="list.rs"
// Обход списка по индексам
let mut _count = 0;
for i in 0..nums.len() {
    _count += nums[i];
}

// Прямой обход элементов списка
_count = 0;
for num in &nums {
    _count += num;
}
```

=== "C"

```c title="list.c"
// В C нет встроенного динамического массива
```

=== "Kotlin"

```kotlin title="list.kt"
/* Обход списка по индексам */
var count = 0
for (i in nums.indices) {
    count += nums[i]
}

/* Прямой обход элементов списка */
for (num in nums) {
    count += num
}
```

=== "Ruby"

```ruby title="list.rb"
# Обход списка по индексам
count = 0
for i in 0...nums.length
    count += nums[i]
end

# Прямой обход элементов списка
count = 0
for num in nums
    count += num
end
```

??? pythontutor "Визуализация выполнения"

https://pythontutor.com/render.html#code=%22%22%22Driver%20Code%22%22%22%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20%23%20%D0%98%D0%BD%D0%B8%D1%86%D0%B8%D0%B0%D0%BB%D0%B8%D0%B7%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D1%82%D1%8C%20%D1%81%D0%BF%D0%B8%D1%81%D0%BE%D0%BA%0A%20%20%20%20nums%20%3D%20%5B1%2C%203%2C%202%2C%205%2C%204%5D%0A%20%20%20%20%0A%20%20%20%20%23%20%D0%9E%D0%B1%D1%85%D0%BE%D0%B4%D0%B8%D1%82%D1%8C%20%D1%81%D0%BF%D0%B8%D1%81%D0%BE%D0%BA%20%D0%BF%D0%BE%20%D0%B8%D0%BD%D0%B4%D0%B5%D0%BA%D1%81%D0%B0%D0%BC%0A%20%20%20%20count%20%3D%200%0A%20%20%20%20for%20i%20in%20range%28len%28nums%29%29%3A%0A%20%20%20%20%20%20%20%20count%20%2B%3D%20nums%5Bi%5D%0A%0A%20%20%20%20%23%20%D0%9D%D0%B5%D0%BF%D0%BE%D1%81%D1%80%D0%B5%D0%B4%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D0%BE%20%D0%BE%D0%B1%D1%85%D0%BE%D0%B4%D0%B8%D1%82%D1%8C%20%D1%8D%D0%BB%D0%B5%D0%BC%D0%B5%D0%BD%D1%82%D1%8B%20%D1%81%D0%BF%D0%B8%D1%81%D0%BA%D0%B0%0A%20%20%20%20for%20num%20in%20nums%3A%0A%20%20%20%20%20%20%20%20count%20%2B%3D%20num&cumulative=false&curInstr=3&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=311&rawInputLstJSON=%5B%5D&textReferences=false

Конкатенация списков

Создав новый список nums1 , мы можем присоединить его к хвосту исходного списка.

=== "Python"

```python title="list.py"
# Конкатенация двух списков
nums1: list[int] = [6, 8, 7, 10, 9]
nums += nums1  # Присоединить список nums1 к концу nums
```

=== "C++"

```cpp title="list.cpp"
/* Конкатенация двух списков */
vector<int> nums1 = { 6, 8, 7, 10, 9 };
// Присоединить список nums1 к концу nums
nums.insert(nums.end(), nums1.begin(), nums1.end());
```

=== "Java"

```java title="list.java"
/* Конкатенация двух списков */
List<Integer> nums1 = new ArrayList<>(Arrays.asList(new Integer[] { 6, 8, 7, 10, 9 }));
nums.addAll(nums1);  // Присоединить список nums1 к концу nums
```

=== "C#"

```csharp title="list.cs"
/* Конкатенация двух списков */
List<int> nums1 = [6, 8, 7, 10, 9];
nums.AddRange(nums1);  // Присоединить список nums1 к концу nums
```

=== "Go"

```go title="list_test.go"
/* Конкатенация двух списков */
nums1 := []int{6, 8, 7, 10, 9}
nums = append(nums, nums1...)  // Присоединить список nums1 к концу nums
```

=== "Swift"

```swift title="list.swift"
/* Конкатенация двух списков */
let nums1 = [6, 8, 7, 10, 9]
nums.append(contentsOf: nums1) // Присоединить список nums1 к концу nums
```

=== "JS"

```javascript title="list.js"
/* Конкатенация двух списков */
const nums1 = [6, 8, 7, 10, 9];
nums.push(...nums1);  // Присоединить список nums1 к концу nums
```

=== "TS"

```typescript title="list.ts"
/* Конкатенация двух списков */
const nums1: number[] = [6, 8, 7, 10, 9];
nums.push(...nums1);  // Присоединить список nums1 к концу nums
```

=== "Dart"

```dart title="list.dart"
/* Конкатенация двух списков */
List<int> nums1 = [6, 8, 7, 10, 9];
nums.addAll(nums1);  // Присоединить список nums1 к концу nums
```

=== "Rust"

```rust title="list.rs"
/* Конкатенация двух списков */
let nums1: Vec<i32> = vec![6, 8, 7, 10, 9];
nums.extend(nums1);
```

=== "C"

```c title="list.c"
// В C нет встроенного динамического массива
```

=== "Kotlin"

```kotlin title="list.kt"
/* Конкатенация двух списков */
val nums1 = intArrayOf(6, 8, 7, 10, 9).toMutableList()
nums.addAll(nums1)  // Присоединить список nums1 к концу nums
```

=== "Ruby"

```ruby title="list.rb"
# Конкатенация двух списков
nums1 = [6, 8, 7, 10, 9]
nums += nums1
```

??? pythontutor "Визуализация выполнения"

https://pythontutor.com/render.html#code=%22%22%22Driver%20Code%22%22%22%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20%23%20%D0%98%D0%BD%D0%B8%D1%86%D0%B8%D0%B0%D0%BB%D0%B8%D0%B7%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D1%82%D1%8C%20%D1%81%D0%BF%D0%B8%D1%81%D0%BE%D0%BA%0A%20%20%20%20nums%20%3D%20%5B1%2C%203%2C%202%2C%205%2C%204%5D%0A%20%20%20%20%0A%20%20%20%20%23%20%D0%9E%D0%B1%D1%8A%D0%B5%D0%B4%D0%B8%D0%BD%D0%B8%D1%82%D1%8C%20%D0%B4%D0%B2%D0%B0%20%D1%81%D0%BF%D0%B8%D1%81%D0%BA%D0%B0%0A%20%20%20%20nums1%20%3D%20%5B6%2C%208%2C%207%2C%2010%2C%209%5D%0A%20%20%20%20nums%20%2B%3D%20nums1%20%20%23%20%D0%9F%D1%80%D0%B8%D1%81%D0%BE%D0%B5%D0%B4%D0%B8%D0%BD%D0%B8%D1%82%D1%8C%20%D1%81%D0%BF%D0%B8%D1%81%D0%BE%D0%BA%20nums1%20%D0%BA%20nums&cumulative=false&curInstr=3&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=311&rawInputLstJSON=%5B%5D&textReferences=false

Сортировка списка

После сортировки списка мы сможем применять алгоритмы "двоичный поиск" и "два указателя", которые очень часто встречаются в задачах по массивам.

=== "Python"

```python title="list.py"
# Отсортировать список
nums.sort()  # После сортировки элементы списка идут по возрастанию
```

=== "C++"

```cpp title="list.cpp"
/* Отсортировать список */
sort(nums.begin(), nums.end());  // После сортировки элементы списка идут по возрастанию
```

=== "Java"

```java title="list.java"
/* Отсортировать список */
Collections.sort(nums);  // После сортировки элементы списка идут по возрастанию
```

=== "C#"

```csharp title="list.cs"
/* Отсортировать список */
nums.Sort(); // После сортировки элементы списка идут по возрастанию
```

=== "Go"

```go title="list_test.go"
/* Отсортировать список */
sort.Ints(nums)  // После сортировки элементы списка идут по возрастанию
```

=== "Swift"

```swift title="list.swift"
/* Отсортировать список */
nums.sort() // После сортировки элементы списка идут по возрастанию
```

=== "JS"

```javascript title="list.js"
/* Отсортировать список */
nums.sort((a, b) => a - b);  // После сортировки элементы списка идут по возрастанию
```

=== "TS"

```typescript title="list.ts"
/* Отсортировать список */
nums.sort((a, b) => a - b);  // После сортировки элементы списка идут по возрастанию
```

=== "Dart"

```dart title="list.dart"
/* Отсортировать список */
nums.sort(); // После сортировки элементы списка идут по возрастанию
```

=== "Rust"

```rust title="list.rs"
/* Отсортировать список */
nums.sort(); // После сортировки элементы списка идут по возрастанию
```

=== "C"

```c title="list.c"
// В C нет встроенного динамического массива
```

=== "Kotlin"

```kotlin title="list.kt"
/* Отсортировать список */
nums.sort() // После сортировки элементы списка идут по возрастанию
```

=== "Ruby"

```ruby title="list.rb"
# Отсортировать список
nums = nums.sort { |a, b| a <=> b } # После сортировки элементы списка идут по возрастанию
```

??? pythontutor "Визуализация выполнения"

https://pythontutor.com/render.html#code=%22%22%22Driver%20Code%22%22%22%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20%23%20%D0%98%D0%BD%D0%B8%D1%86%D0%B8%D0%B0%D0%BB%D0%B8%D0%B7%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D1%82%D1%8C%20%D1%81%D0%BF%D0%B8%D1%81%D0%BE%D0%BA%0A%20%20%20%20nums%20%3D%20%5B1%2C%203%2C%202%2C%205%2C%204%5D%0A%20%20%20%20%0A%20%20%20%20%23%20%D0%9E%D1%82%D1%81%D0%BE%D1%80%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D1%82%D1%8C%20%D1%81%D0%BF%D0%B8%D1%81%D0%BE%D0%BA%0A%20%20%20%20nums.sort%28%29%20%20%23%20%D0%A1%D0%BE%D1%80%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%BA%D0%B0%D0%BF%D0%BE%D1%81%D0%BB%D0%B5%2C%20%D1%81%D0%BF%D0%B8%D1%81%D0%BE%D0%BA%D1%8D%D0%BB%D0%B5%D0%BC%D0%B5%D0%BD%D1%82%D1%80%D0%B0%D1%81%D0%BF%D0%BE%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D1%8B%20%D0%BF%D0%BE%20%D0%B2%D0%BE%D0%B7%D1%80%D0%B0%D1%81%D1%82%D0%B0%D0%BD%D0%B8%D1%8E&cumulative=false&curInstr=3&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=311&rawInputLstJSON=%5B%5D&textReferences=false

Реализация списка

Во многих языках программирования списки встроены в стандартную библиотеку, например в Java, C++, Python и других языках. Их реализация довольно сложна, а настройки параметров тщательно продуманы: начальная емкость, коэффициент расширения и так далее. Если это интересно, стоит заглянуть в исходный код.

Чтобы лучше понять принцип работы списка, попробуем реализовать его упрощенную версию, в которой есть три ключевых аспекта проектирования.

  • Начальная емкость: выбрать разумную начальную емкость внутреннего массива. В этом примере мы берем 10.
  • Учет количества элементов: объявить переменную size , которая будет хранить текущее число элементов в списке и обновляться в реальном времени при вставке и удалении элементов. С помощью этой переменной можно определять конец списка и понимать, требуется ли расширение.
  • Механизм расширения: если при вставке элементов емкость списка исчерпана, нужно выполнить расширение. Для этого сначала создается больший массив с учетом коэффициента расширения, а затем все элементы текущего массива по порядку переносятся в новый. В этом примере мы считаем, что каждый раз массив расширяется в 2 раза.
[file]{my_list}-[class]{my_list}-[func]{}