# Список Список (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 nums1; // С начальными значениями vector nums = { 1, 3, 2, 5, 4 }; ``` === "Java" ```java title="list.java" /* Инициализация списка */ // Без начальных значений List nums1 = new ArrayList<>(); // С начальными значениями (обрати внимание: элементы массива должны использовать обертку Integer[] вместо int[]) Integer[] numbers = new Integer[] { 1, 3, 2, 5, 4 }; List nums = new ArrayList<>(Arrays.asList(numbers)); ``` === "C#" ```csharp title="list.cs" /* Инициализация списка */ // Без начальных значений List nums1 = []; // С начальными значениями int[] numbers = [1, 3, 2, 5, 4]; List 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 nums1 = []; // С начальными значениями List nums = [1, 3, 2, 5, 4]; ``` === "Rust" ```rust title="list.rs" /* Инициализация списка */ // Без начальных значений let nums1: Vec = Vec::new(); // С начальными значениями let nums: Vec = vec![1, 3, 2, 5, 4]; ``` === "C" ```c title="list.c" // В C нет встроенного динамического массива ``` === "Kotlin" ```kotlin title="list.kt" /* Инициализация списка */ // Без начальных значений var nums1 = listOf() // С начальными значениями 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 nums1 = { 6, 8, 7, 10, 9 }; // Присоединить список nums1 к концу nums nums.insert(nums.end(), nums1.begin(), nums1.end()); ``` === "Java" ```java title="list.java" /* Конкатенация двух списков */ List nums1 = new ArrayList<>(Arrays.asList(new Integer[] { 6, 8, 7, 10, 9 })); nums.addAll(nums1); // Присоединить список nums1 к концу nums ``` === "C#" ```csharp title="list.cs" /* Конкатенация двух списков */ List 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 nums1 = [6, 8, 7, 10, 9]; nums.addAll(nums1); // Присоединить список nums1 к концу nums ``` === "Rust" ```rust title="list.rs" /* Конкатенация двух списков */ let nums1: Vec = 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 раза. ```src [file]{my_list}-[class]{my_list}-[func]{} ```