From 1e94fab579c4e72058a90ae9991a2ea7c60bdf71 Mon Sep 17 00:00:00 2001 From: krahets Date: Tue, 27 Oct 2026 19:15:55 +0800 Subject: [PATCH] build --- ru/docs/chapter_array_and_linkedlist/array.md | 198 +++++++++--------- .../linked_list.md | 154 +++++++------- ru/docs/chapter_array_and_linkedlist/list.md | 134 ++++++------ .../ram_and_cache.md | 4 +- .../basic_data_types.md | 2 +- .../chapter_data_structure/number_encoding.md | 2 +- .../binary_search_recur.md | 56 ++--- ru/docs/chapter_hashing/hash_algorithm.md | 4 +- ru/docs/chapter_hashing/hash_collision.md | 2 +- ru/docs/chapter_searching/binary_search.md | 116 +++++----- .../chapter_searching/binary_search_edge.md | 112 +++++----- .../binary_search_insertion.md | 138 ++++++------ ru/docs/chapter_searching/exercises.md | 6 +- ru/docs/chapter_searching/index.md | 2 +- .../replace_linear_by_hashing.md | 2 +- .../searching_algorithm_revisited.md | 4 +- ru/docs/chapter_stack_and_queue/deque.md | 22 +- ru/docs/chapter_stack_and_queue/queue.md | 2 +- 18 files changed, 480 insertions(+), 480 deletions(-) diff --git a/ru/docs/chapter_array_and_linkedlist/array.md b/ru/docs/chapter_array_and_linkedlist/array.md index ca654b767..a188bf03d 100644 --- a/ru/docs/chapter_array_and_linkedlist/array.md +++ b/ru/docs/chapter_array_and_linkedlist/array.md @@ -154,7 +154,7 @@ comments: true ```python title="array.py" def random_access(nums: list[int]) -> int: """Случайный доступ к элементу""" - # Случайным образом выбрать число из интервала [0, len(nums)-1] + # Случайный выбор числа из диапазона [0, len(nums)-1] random_index = random.randint(0, len(nums) - 1) # Получить и вернуть случайный элемент random_num = nums[random_index] @@ -166,7 +166,7 @@ comments: true ```cpp title="array.cpp" /* Случайный доступ к элементу */ int randomAccess(int *nums, int size) { - // Случайным образом выбрать число из интервала [0, size) + // Случайный выбор числа из диапазона [0, size) int randomIndex = rand() % size; // Получить и вернуть случайный элемент int randomNum = nums[randomIndex]; @@ -179,7 +179,7 @@ comments: true ```java title="array.java" /* Случайный доступ к элементу */ int randomAccess(int[] nums) { - // Случайным образом выбрать число из интервала [0, nums.length) + // Случайный выбор числа из диапазона [0, nums.length) int randomIndex = ThreadLocalRandom.current().nextInt(0, nums.length); // Получить и вернуть случайный элемент int randomNum = nums[randomIndex]; @@ -193,7 +193,7 @@ comments: true /* Случайный доступ к элементу */ int RandomAccess(int[] nums) { Random random = new(); - // Случайным образом выбрать число из интервала [0, nums.Length) + // Случайный выбор числа из диапазона [0, nums.Length) int randomIndex = random.Next(nums.Length); // Получить и вернуть случайный элемент int randomNum = nums[randomIndex]; @@ -206,7 +206,7 @@ comments: true ```go title="array.go" /* Случайный доступ к элементу */ func randomAccess(nums []int) (randomNum int) { - // Случайным образом выбрать число из интервала [0, nums.length) + // Случайный выбор числа из диапазона [0, nums.length) randomIndex := rand.Intn(len(nums)) // Получить и вернуть случайный элемент randomNum = nums[randomIndex] @@ -219,7 +219,7 @@ comments: true ```swift title="array.swift" /* Случайный доступ к элементу */ func randomAccess(nums: [Int]) -> Int { - // Случайным образом выбрать число из интервала [0, nums.count) + // Случайный выбор числа из диапазона [0, nums.count) let randomIndex = nums.indices.randomElement()! // Получить и вернуть случайный элемент let randomNum = nums[randomIndex] @@ -232,7 +232,7 @@ comments: true ```javascript title="array.js" /* Случайный доступ к элементу */ function randomAccess(nums) { - // Случайным образом выбрать число из интервала [0, nums.length) + // Случайный выбор числа из диапазона [0, nums.length) const random_index = Math.floor(Math.random() * nums.length); // Получить и вернуть случайный элемент const random_num = nums[random_index]; @@ -245,7 +245,7 @@ comments: true ```typescript title="array.ts" /* Случайный доступ к элементу */ function randomAccess(nums: number[]): number { - // Случайным образом выбрать число из интервала [0, nums.length) + // Случайный выбор числа из диапазона [0, nums.length) const random_index = Math.floor(Math.random() * nums.length); // Получить и вернуть случайный элемент const random_num = nums[random_index]; @@ -258,7 +258,7 @@ comments: true ```dart title="array.dart" /* Случайный доступ к элементу */ int randomAccess(List nums) { - // Случайным образом выбрать число из интервала [0, nums.length) + // Случайный выбор числа из диапазона [0, nums.length) int randomIndex = Random().nextInt(nums.length); // Получить и вернуть случайный элемент int randomNum = nums[randomIndex]; @@ -271,7 +271,7 @@ comments: true ```rust title="array.rs" /* Случайный доступ к элементу */ fn random_access(nums: &[i32]) -> i32 { - // Случайным образом выбрать число из интервала [0, nums.len()) + // Случайный выбор числа из диапазона [0, nums.len()) let random_index = rand::thread_rng().gen_range(0..nums.len()); // Получить и вернуть случайный элемент let random_num = nums[random_index]; @@ -284,7 +284,7 @@ comments: true ```c title="array.c" /* Случайный доступ к элементу */ int randomAccess(int *nums, int size) { - // Случайным образом выбрать число из интервала [0, size) + // Случайный выбор числа из диапазона [0, size) int randomIndex = rand() % size; // Получить и вернуть случайный элемент int randomNum = nums[randomIndex]; @@ -297,7 +297,7 @@ comments: true ```kotlin title="array.kt" /* Случайный доступ к элементу */ fun randomAccess(nums: IntArray): Int { - // Случайным образом выбрать число из интервала [0, nums.size) + // Случайный выбор числа из диапазона [0, nums.size) val randomIndex = ThreadLocalRandom.current().nextInt(0, nums.size) // Получить и вернуть случайный элемент val randomNum = nums[randomIndex] @@ -310,7 +310,7 @@ comments: true ```ruby title="array.rb" ### Случайный доступ к элементу ### def random_access(nums) - # Случайным образом выбрать число из интервала [0, nums.length) + # Случайный выбор числа из диапазона [0, nums.length) random_index = Random.rand(0...nums.length) # Получить и вернуть случайный элемент @@ -320,8 +320,8 @@ comments: true ??? pythontutor "Визуализация кода" -
-
Во весь экран >
+
+
Во весь экран >
### 3.   Вставка элемента @@ -337,8 +337,8 @@ comments: true ```python title="array.py" def insert(nums: list[int], num: int, index: int): - """Вставить элемент num по индексу index в массив""" - # Сдвинуть элемент с индексом index и все последующие элементы на одну позицию назад + """Вставка элемента num в массив по индексу index""" + # Сдвинуть элемент с индексом index и все последующие элементы на одну позицию вправо for i in range(len(nums) - 1, index, -1): nums[i] = nums[i - 1] # Присвоить num элементу по индексу index @@ -348,9 +348,9 @@ comments: true === "C++" ```cpp title="array.cpp" - /* Вставить элемент num по индексу index в массив */ + /* Вставка элемента num в массив по индексу index */ void insert(int *nums, int size, int num, int index) { - // Сдвинуть элемент с индексом index и все последующие элементы на одну позицию назад + // Сдвинуть элемент с индексом index и все последующие элементы на одну позицию вправо for (int i = size - 1; i > index; i--) { nums[i] = nums[i - 1]; } @@ -362,9 +362,9 @@ comments: true === "Java" ```java title="array.java" - /* Вставить элемент num по индексу index в массив */ + /* Вставка элемента num в массив по индексу index */ void insert(int[] nums, int num, int index) { - // Сдвинуть элемент с индексом index и все последующие элементы на одну позицию назад + // Сдвинуть элемент с индексом index и все последующие элементы на одну позицию вправо for (int i = nums.length - 1; i > index; i--) { nums[i] = nums[i - 1]; } @@ -376,9 +376,9 @@ comments: true === "C#" ```csharp title="array.cs" - /* Вставить элемент num по индексу index в массив */ + /* Вставка элемента num в массив по индексу index */ void Insert(int[] nums, int num, int index) { - // Сдвинуть элемент с индексом index и все последующие элементы на одну позицию назад + // Сдвинуть элемент с индексом index и все последующие элементы на одну позицию вправо for (int i = nums.Length - 1; i > index; i--) { nums[i] = nums[i - 1]; } @@ -390,9 +390,9 @@ comments: true === "Go" ```go title="array.go" - /* Вставить элемент num по индексу index в массив */ + /* Вставка элемента num в массив по индексу index */ func insert(nums []int, num int, index int) { - // Сдвинуть элемент с индексом index и все последующие элементы на одну позицию назад + // Сдвинуть элемент с индексом index и все последующие элементы на одну позицию вправо for i := len(nums) - 1; i > index; i-- { nums[i] = nums[i-1] } @@ -404,9 +404,9 @@ comments: true === "Swift" ```swift title="array.swift" - /* Вставить элемент num по индексу index в массив */ + /* Вставка элемента num в массив по индексу index */ func insert(nums: inout [Int], num: Int, index: Int) { - // Сдвинуть элемент с индексом index и все последующие элементы на одну позицию назад + // Сдвинуть элемент с индексом index и все последующие элементы на одну позицию вправо for i in stride(from: nums.count - 1, to: index, by: -1) { nums[i] = nums[i - 1] } @@ -418,9 +418,9 @@ comments: true === "JS" ```javascript title="array.js" - /* Вставить элемент num по индексу index в массив */ + /* Вставка элемента num в массив по индексу index */ function insert(nums, num, index) { - // Сдвинуть элемент с индексом index и все последующие элементы на одну позицию назад + // Сдвинуть элемент с индексом index и все последующие элементы на одну позицию вправо for (let i = nums.length - 1; i > index; i--) { nums[i] = nums[i - 1]; } @@ -432,9 +432,9 @@ comments: true === "TS" ```typescript title="array.ts" - /* Вставить элемент num по индексу index в массив */ + /* Вставка элемента num в массив по индексу index */ function insert(nums: number[], num: number, index: number): void { - // Сдвинуть элемент с индексом index и все последующие элементы на одну позицию назад + // Сдвинуть элемент с индексом index и все последующие элементы на одну позицию вправо for (let i = nums.length - 1; i > index; i--) { nums[i] = nums[i - 1]; } @@ -446,9 +446,9 @@ comments: true === "Dart" ```dart title="array.dart" - /* Вставить элемент _num по индексу index в массив */ + /* Вставка элемента _num в массив по индексу index */ void insert(List nums, int _num, int index) { - // Сдвинуть элемент с индексом index и все последующие элементы на одну позицию назад + // Сдвинуть элемент с индексом index и все последующие элементы на одну позицию вправо for (var i = nums.length - 1; i > index; i--) { nums[i] = nums[i - 1]; } @@ -460,9 +460,9 @@ comments: true === "Rust" ```rust title="array.rs" - /* Вставить элемент num по индексу index в массив */ + /* Вставка элемента num в массив по индексу index */ fn insert(nums: &mut [i32], num: i32, index: usize) { - // Сдвинуть элемент с индексом index и все последующие элементы на одну позицию назад + // Сдвинуть элемент с индексом index и все последующие элементы на одну позицию вправо for i in (index + 1..nums.len()).rev() { nums[i] = nums[i - 1]; } @@ -474,9 +474,9 @@ comments: true === "C" ```c title="array.c" - /* Вставить элемент num по индексу index в массив */ + /* Вставка элемента num в массив по индексу index */ void insert(int *nums, int size, int num, int index) { - // Сдвинуть элемент с индексом index и все последующие элементы на одну позицию назад + // Сдвинуть элемент с индексом index и все последующие элементы на одну позицию вправо for (int i = size - 1; i > index; i--) { nums[i] = nums[i - 1]; } @@ -488,9 +488,9 @@ comments: true === "Kotlin" ```kotlin title="array.kt" - /* Вставить элемент num по индексу index в массив */ + /* Вставка элемента num в массив по индексу index */ fun insert(nums: IntArray, num: Int, index: Int) { - // Сдвинуть элемент с индексом index и все последующие элементы на одну позицию назад + // Сдвинуть элемент с индексом index и все последующие элементы на одну позицию вправо for (i in nums.size - 1 downTo index + 1) { nums[i] = nums[i - 1] } @@ -502,9 +502,9 @@ comments: true === "Ruby" ```ruby title="array.rb" - ### Вставка элемента num по индексу index в массив ### + ### Вставка элемента num в массив по индексу index ### def insert(nums, num, index) - # Сдвинуть элемент с индексом index и все последующие элементы на одну позицию назад + # Сдвинуть элемент с индексом index и все последующие элементы на одну позицию вправо for i in (nums.length - 1).downto(index + 1) nums[i] = nums[i - 1] end @@ -516,8 +516,8 @@ comments: true ??? pythontutor "Визуализация кода" -
-
Во весь экран >
+
+
Во весь экран >
### 4.   Удаление элемента @@ -533,8 +533,8 @@ comments: true ```python title="array.py" def remove(nums: list[int], index: int): - """Удалить элемент по индексу index""" - # Сдвинуть все элементы после индекса index на одну позицию вперед + """Удаление элемента по индексу index""" + # Сдвинуть все элементы после индекса index на одну позицию влево for i in range(index, len(nums) - 1): nums[i] = nums[i + 1] ``` @@ -542,9 +542,9 @@ comments: true === "C++" ```cpp title="array.cpp" - /* Удалить элемент по индексу index */ + /* Удаление элемента по индексу index */ void remove(int *nums, int size, int index) { - // Сдвинуть все элементы после индекса index на одну позицию вперед + // Сдвинуть все элементы после индекса index на одну позицию влево for (int i = index; i < size - 1; i++) { nums[i] = nums[i + 1]; } @@ -554,9 +554,9 @@ comments: true === "Java" ```java title="array.java" - /* Удалить элемент по индексу index */ + /* Удаление элемента по индексу index */ void remove(int[] nums, int index) { - // Сдвинуть все элементы после индекса index на одну позицию вперед + // Сдвинуть все элементы после индекса index на одну позицию влево for (int i = index; i < nums.length - 1; i++) { nums[i] = nums[i + 1]; } @@ -566,9 +566,9 @@ comments: true === "C#" ```csharp title="array.cs" - /* Удалить элемент по индексу index */ + /* Удаление элемента по индексу index */ void Remove(int[] nums, int index) { - // Сдвинуть все элементы после индекса index на одну позицию вперед + // Сдвинуть все элементы после индекса index на одну позицию влево for (int i = index; i < nums.Length - 1; i++) { nums[i] = nums[i + 1]; } @@ -578,9 +578,9 @@ comments: true === "Go" ```go title="array.go" - /* Удалить элемент по индексу index */ + /* Удаление элемента по индексу index */ func remove(nums []int, index int) { - // Сдвинуть все элементы после индекса index на одну позицию вперед + // Сдвинуть все элементы после индекса index на одну позицию влево for i := index; i < len(nums)-1; i++ { nums[i] = nums[i+1] } @@ -590,9 +590,9 @@ comments: true === "Swift" ```swift title="array.swift" - /* Удалить элемент по индексу index */ + /* Удаление элемента по индексу index */ func remove(nums: inout [Int], index: Int) { - // Сдвинуть все элементы после индекса index на одну позицию вперед + // Сдвинуть все элементы после индекса index на одну позицию влево for i in nums.indices.dropFirst(index).dropLast() { nums[i] = nums[i + 1] } @@ -602,9 +602,9 @@ comments: true === "JS" ```javascript title="array.js" - /* Удалить элемент по индексу index */ + /* Удаление элемента по индексу index */ function remove(nums, index) { - // Сдвинуть все элементы после индекса index на одну позицию вперед + // Сдвинуть все элементы после индекса index на одну позицию влево for (let i = index; i < nums.length - 1; i++) { nums[i] = nums[i + 1]; } @@ -614,9 +614,9 @@ comments: true === "TS" ```typescript title="array.ts" - /* Удалить элемент по индексу index */ + /* Удаление элемента по индексу index */ function remove(nums: number[], index: number): void { - // Сдвинуть все элементы после индекса index на одну позицию вперед + // Сдвинуть все элементы после индекса index на одну позицию влево for (let i = index; i < nums.length - 1; i++) { nums[i] = nums[i + 1]; } @@ -626,9 +626,9 @@ comments: true === "Dart" ```dart title="array.dart" - /* Удалить элемент по индексу index */ + /* Удаление элемента по индексу index */ void remove(List nums, int index) { - // Сдвинуть все элементы после индекса index на одну позицию вперед + // Сдвинуть все элементы после индекса index на одну позицию влево for (var i = index; i < nums.length - 1; i++) { nums[i] = nums[i + 1]; } @@ -638,9 +638,9 @@ comments: true === "Rust" ```rust title="array.rs" - /* Удалить элемент по индексу index */ + /* Удаление элемента по индексу index */ fn remove(nums: &mut [i32], index: usize) { - // Сдвинуть все элементы после индекса index на одну позицию вперед + // Сдвинуть все элементы после индекса index на одну позицию влево for i in index..nums.len() - 1 { nums[i] = nums[i + 1]; } @@ -650,10 +650,10 @@ comments: true === "C" ```c title="array.c" - /* Удалить элемент по индексу index */ + /* Удаление элемента по индексу index */ // Внимание: stdio.h уже использует ключевое слово remove void removeItem(int *nums, int size, int index) { - // Сдвинуть все элементы после индекса index на одну позицию вперед + // Сдвинуть все элементы после индекса index на одну позицию влево for (int i = index; i < size - 1; i++) { nums[i] = nums[i + 1]; } @@ -663,9 +663,9 @@ comments: true === "Kotlin" ```kotlin title="array.kt" - /* Удалить элемент по индексу index */ + /* Удаление элемента по индексу index */ fun remove(nums: IntArray, index: Int) { - // Сдвинуть все элементы после индекса index на одну позицию вперед + // Сдвинуть все элементы после индекса index на одну позицию влево for (i in index.. - +
+ В целом операции вставки и удаления в массиве имеют следующие недостатки. @@ -946,7 +946,7 @@ comments: true ```python title="array.py" def find(nums: list[int], target: int) -> int: - """Найти заданный элемент в массиве""" + """Поиск заданного элемента в массиве""" for i in range(len(nums)): if nums[i] == target: return i @@ -956,7 +956,7 @@ comments: true === "C++" ```cpp title="array.cpp" - /* Найти заданный элемент в массиве */ + /* Поиск заданного элемента в массиве */ int find(int *nums, int size, int target) { for (int i = 0; i < size; i++) { if (nums[i] == target) @@ -969,7 +969,7 @@ comments: true === "Java" ```java title="array.java" - /* Найти заданный элемент в массиве */ + /* Поиск заданного элемента в массиве */ int find(int[] nums, int target) { for (int i = 0; i < nums.length; i++) { if (nums[i] == target) @@ -982,7 +982,7 @@ comments: true === "C#" ```csharp title="array.cs" - /* Найти заданный элемент в массиве */ + /* Поиск заданного элемента в массиве */ int Find(int[] nums, int target) { for (int i = 0; i < nums.Length; i++) { if (nums[i] == target) @@ -995,7 +995,7 @@ comments: true === "Go" ```go title="array.go" - /* Найти заданный элемент в массиве */ + /* Поиск заданного элемента в массиве */ func find(nums []int, target int) (index int) { index = -1 for i := 0; i < len(nums); i++ { @@ -1011,7 +1011,7 @@ comments: true === "Swift" ```swift title="array.swift" - /* Найти заданный элемент в массиве */ + /* Поиск заданного элемента в массиве */ func find(nums: [Int], target: Int) -> Int { for i in nums.indices { if nums[i] == target { @@ -1025,7 +1025,7 @@ comments: true === "JS" ```javascript title="array.js" - /* Найти заданный элемент в массиве */ + /* Поиск заданного элемента в массиве */ function find(nums, target) { for (let i = 0; i < nums.length; i++) { if (nums[i] === target) return i; @@ -1037,7 +1037,7 @@ comments: true === "TS" ```typescript title="array.ts" - /* Найти заданный элемент в массиве */ + /* Поиск заданного элемента в массиве */ function find(nums: number[], target: number): number { for (let i = 0; i < nums.length; i++) { if (nums[i] === target) { @@ -1051,7 +1051,7 @@ comments: true === "Dart" ```dart title="array.dart" - /* Найти заданный элемент в массиве */ + /* Поиск заданного элемента в массиве */ int find(List nums, int target) { for (var i = 0; i < nums.length; i++) { if (nums[i] == target) return i; @@ -1063,7 +1063,7 @@ comments: true === "Rust" ```rust title="array.rs" - /* Найти заданный элемент в массиве */ + /* Поиск заданного элемента в массиве */ fn find(nums: &[i32], target: i32) -> Option { for i in 0..nums.len() { if nums[i] == target { @@ -1077,7 +1077,7 @@ comments: true === "C" ```c title="array.c" - /* Найти заданный элемент в массиве */ + /* Поиск заданного элемента в массиве */ int find(int *nums, int size, int target) { for (int i = 0; i < size; i++) { if (nums[i] == target) @@ -1090,7 +1090,7 @@ comments: true === "Kotlin" ```kotlin title="array.kt" - /* Найти заданный элемент в массиве */ + /* Поиск заданного элемента в массиве */ fun find(nums: IntArray, target: Int): Int { for (i in nums.indices) { if (nums[i] == target) @@ -1115,8 +1115,8 @@ comments: true ??? pythontutor "Визуализация кода" -
- +
+ ### 7.   Расширение массива @@ -1128,7 +1128,7 @@ comments: true ```python title="array.py" def extend(nums: list[int], enlarge: int) -> list[int]: - """Увеличить длину массива""" + """Увеличение длины массива""" # Инициализировать массив увеличенной длины res = [0] * (len(nums) + enlarge) # Скопировать все элементы исходного массива в новый массив @@ -1141,7 +1141,7 @@ comments: true === "C++" ```cpp title="array.cpp" - /* Увеличить длину массива */ + /* Увеличение длины массива */ int *extend(int *nums, int size, int enlarge) { // Инициализировать массив увеличенной длины int *res = new int[size + enlarge]; @@ -1159,7 +1159,7 @@ comments: true === "Java" ```java title="array.java" - /* Увеличить длину массива */ + /* Увеличение длины массива */ int[] extend(int[] nums, int enlarge) { // Инициализировать массив увеличенной длины int[] res = new int[nums.length + enlarge]; @@ -1175,7 +1175,7 @@ comments: true === "C#" ```csharp title="array.cs" - /* Увеличить длину массива */ + /* Увеличение длины массива */ int[] Extend(int[] nums, int enlarge) { // Инициализировать массив увеличенной длины int[] res = new int[nums.Length + enlarge]; @@ -1191,7 +1191,7 @@ comments: true === "Go" ```go title="array.go" - /* Увеличить длину массива */ + /* Увеличение длины массива */ func extend(nums []int, enlarge int) []int { // Инициализировать массив увеличенной длины res := make([]int, len(nums)+enlarge) @@ -1207,7 +1207,7 @@ comments: true === "Swift" ```swift title="array.swift" - /* Увеличить длину массива */ + /* Увеличение длины массива */ func extend(nums: [Int], enlarge: Int) -> [Int] { // Инициализировать массив увеличенной длины var res = Array(repeating: 0, count: nums.count + enlarge) @@ -1223,7 +1223,7 @@ comments: true === "JS" ```javascript title="array.js" - /* Увеличить длину массива */ + /* Увеличение длины массива */ // Обратите внимание: Array в JavaScript — это динамический массив, его можно расширять напрямую // Для удобства обучения в этой функции Array рассматривается как массив неизменяемой длины function extend(nums, enlarge) { @@ -1241,7 +1241,7 @@ comments: true === "TS" ```typescript title="array.ts" - /* Увеличить длину массива */ + /* Увеличение длины массива */ // Обратите внимание: Array в TypeScript — это динамический массив, его можно расширять напрямую // Для удобства обучения в этой функции Array рассматривается как массив неизменяемой длины function extend(nums: number[], enlarge: number): number[] { @@ -1259,7 +1259,7 @@ comments: true === "Dart" ```dart title="array.dart" - /* Увеличить длину массива */ + /* Увеличение длины массива */ List extend(List nums, int enlarge) { // Инициализировать массив увеличенной длины List res = List.filled(nums.length + enlarge, 0); @@ -1275,7 +1275,7 @@ comments: true === "Rust" ```rust title="array.rs" - /* Увеличить длину массива */ + /* Увеличение длины массива */ fn extend(nums: &[i32], enlarge: usize) -> Vec { // Инициализировать массив увеличенной длины let mut res: Vec = vec![0; nums.len() + enlarge]; @@ -1290,7 +1290,7 @@ comments: true === "C" ```c title="array.c" - /* Увеличить длину массива */ + /* Увеличение длины массива */ int *extend(int *nums, int size, int enlarge) { // Инициализировать массив увеличенной длины int *res = (int *)malloc(sizeof(int) * (size + enlarge)); @@ -1310,7 +1310,7 @@ comments: true === "Kotlin" ```kotlin title="array.kt" - /* Увеличить длину массива */ + /* Увеличение длины массива */ fun extend(nums: IntArray, enlarge: Int): IntArray { // Инициализировать массив увеличенной длины val res = IntArray(nums.size + enlarge) @@ -1326,7 +1326,7 @@ comments: true === "Ruby" ```ruby title="array.rb" - ### Увеличить длину массива ### + ### Увеличение длины массива ### # Обратите внимание: Array в Ruby является динамическим массивом и может расширяться напрямую # Для удобства обучения в этой функции Array рассматривается как массив неизменяемой длины def extend(nums, enlarge) @@ -1345,8 +1345,8 @@ comments: true ??? pythontutor "Визуализация кода" -
- +
+ ## 4.1.2   Преимущества и ограничения массива diff --git a/ru/docs/chapter_array_and_linkedlist/linked_list.md b/ru/docs/chapter_array_and_linkedlist/linked_list.md index 8609e9bf5..cf9c991c1 100644 --- a/ru/docs/chapter_array_and_linkedlist/linked_list.md +++ b/ru/docs/chapter_array_and_linkedlist/linked_list.md @@ -73,7 +73,7 @@ comments: true Next *ListNode // Указатель на следующий узел } - // NewListNode Конструктор, создает новый узел + // NewListNode — функция-конструктор, создающая новый связный список. func NewListNode(val int) *ListNode { return &ListNode{ Val: val, @@ -201,7 +201,7 @@ comments: true ```python title="linked_list.py" # Инициализация связного списка 1 -> 3 -> 2 -> 5 -> 4 - # Инициализация отдельных узлов + # Инициализация каждого узла n0 = ListNode(1) n1 = ListNode(3) n2 = ListNode(2) @@ -218,7 +218,7 @@ comments: true ```cpp title="linked_list.cpp" /* Инициализация связного списка 1 -> 3 -> 2 -> 5 -> 4 */ - // Инициализация отдельных узлов + // Инициализация каждого узла ListNode* n0 = new ListNode(1); ListNode* n1 = new ListNode(3); ListNode* n2 = new ListNode(2); @@ -235,7 +235,7 @@ comments: true ```java title="linked_list.java" /* Инициализация связного списка 1 -> 3 -> 2 -> 5 -> 4 */ - // Инициализация отдельных узлов + // Инициализация каждого узла ListNode n0 = new ListNode(1); ListNode n1 = new ListNode(3); ListNode n2 = new ListNode(2); @@ -252,7 +252,7 @@ comments: true ```csharp title="linked_list.cs" /* Инициализация связного списка 1 -> 3 -> 2 -> 5 -> 4 */ - // Инициализация отдельных узлов + // Инициализация каждого узла ListNode n0 = new(1); ListNode n1 = new(3); ListNode n2 = new(2); @@ -269,7 +269,7 @@ comments: true ```go title="linked_list.go" /* Инициализация связного списка 1 -> 3 -> 2 -> 5 -> 4 */ - // Инициализация отдельных узлов + // Инициализация каждого узла n0 := NewListNode(1) n1 := NewListNode(3) n2 := NewListNode(2) @@ -286,7 +286,7 @@ comments: true ```swift title="linked_list.swift" /* Инициализация связного списка 1 -> 3 -> 2 -> 5 -> 4 */ - // Инициализация отдельных узлов + // Инициализация каждого узла let n0 = ListNode(x: 1) let n1 = ListNode(x: 3) let n2 = ListNode(x: 2) @@ -303,7 +303,7 @@ comments: true ```javascript title="linked_list.js" /* Инициализация связного списка 1 -> 3 -> 2 -> 5 -> 4 */ - // Инициализация отдельных узлов + // Инициализация каждого узла const n0 = new ListNode(1); const n1 = new ListNode(3); const n2 = new ListNode(2); @@ -320,7 +320,7 @@ comments: true ```typescript title="linked_list.ts" /* Инициализация связного списка 1 -> 3 -> 2 -> 5 -> 4 */ - // Инициализация отдельных узлов + // Инициализация каждого узла const n0 = new ListNode(1); const n1 = new ListNode(3); const n2 = new ListNode(2); @@ -337,7 +337,7 @@ comments: true ```dart title="linked_list.dart" /* Инициализация связного списка 1 -> 3 -> 2 -> 5 -> 4 */\ - // Инициализация отдельных узлов + // Инициализация каждого узла ListNode n0 = ListNode(1); ListNode n1 = ListNode(3); ListNode n2 = ListNode(2); @@ -354,7 +354,7 @@ comments: true ```rust title="linked_list.rs" /* Инициализация связного списка 1 -> 3 -> 2 -> 5 -> 4 */ - // Инициализация отдельных узлов + // Инициализация каждого узла let n0 = Rc::new(RefCell::new(ListNode { val: 1, next: None })); let n1 = Rc::new(RefCell::new(ListNode { val: 3, next: None })); let n2 = Rc::new(RefCell::new(ListNode { val: 2, next: None })); @@ -372,7 +372,7 @@ comments: true ```c title="linked_list.c" /* Инициализация связного списка 1 -> 3 -> 2 -> 5 -> 4 */ - // Инициализация отдельных узлов + // Инициализация каждого узла ListNode* n0 = newListNode(1); ListNode* n1 = newListNode(3); ListNode* n2 = newListNode(2); @@ -389,7 +389,7 @@ comments: true ```kotlin title="linked_list.kt" /* Инициализация связного списка 1 -> 3 -> 2 -> 5 -> 4 */ - // Инициализация отдельных узлов + // Инициализация каждого узла val n0 = ListNode(1) val n1 = ListNode(3) val n2 = ListNode(2) @@ -406,7 +406,7 @@ comments: true ```ruby title="linked_list.rb" # Инициализация связного списка 1 -> 3 -> 2 -> 5 -> 4 - # Инициализация отдельных узлов + # Инициализация каждого узла n0 = ListNode.new(1) n1 = ListNode.new(3) n2 = ListNode.new(2) @@ -440,7 +440,7 @@ comments: true ```python title="linked_list.py" def insert(n0: ListNode, P: ListNode): - """Вставить узел P после узла n0 в связном списке""" + """Вставка узла P в связный список после узла n0""" n1 = n0.next P.next = n1 n0.next = P @@ -449,7 +449,7 @@ comments: true === "C++" ```cpp title="linked_list.cpp" - /* Вставить узел P после узла n0 в связном списке */ + /* Вставка узла P в связный список после узла n0 */ void insert(ListNode *n0, ListNode *P) { ListNode *n1 = n0->next; P->next = n1; @@ -460,7 +460,7 @@ comments: true === "Java" ```java title="linked_list.java" - /* Вставить узел P после узла n0 в связном списке */ + /* Вставка узла P в связный список после узла n0 */ void insert(ListNode n0, ListNode P) { ListNode n1 = n0.next; P.next = n1; @@ -471,7 +471,7 @@ comments: true === "C#" ```csharp title="linked_list.cs" - /* Вставить узел P после узла n0 в связном списке */ + /* Вставка узла P в связный список после узла n0 */ void Insert(ListNode n0, ListNode P) { ListNode? n1 = n0.next; P.next = n1; @@ -482,7 +482,7 @@ comments: true === "Go" ```go title="linked_list.go" - /* Вставить узел P после узла n0 в связном списке */ + /* Вставка узла P в связный список после узла n0 */ func insertNode(n0 *ListNode, P *ListNode) { n1 := n0.Next P.Next = n1 @@ -493,7 +493,7 @@ comments: true === "Swift" ```swift title="linked_list.swift" - /* Вставить узел P после узла n0 в связном списке */ + /* Вставка узла P в связный список после узла n0 */ func insert(n0: ListNode, P: ListNode) { let n1 = n0.next P.next = n1 @@ -504,7 +504,7 @@ comments: true === "JS" ```javascript title="linked_list.js" - /* Вставить узел P после узла n0 в связном списке */ + /* Вставка узла P в связный список после узла n0 */ function insert(n0, P) { const n1 = n0.next; P.next = n1; @@ -515,7 +515,7 @@ comments: true === "TS" ```typescript title="linked_list.ts" - /* Вставить узел P после узла n0 в связном списке */ + /* Вставка узла P в связный список после узла n0 */ function insert(n0: ListNode, P: ListNode): void { const n1 = n0.next; P.next = n1; @@ -526,7 +526,7 @@ comments: true === "Dart" ```dart title="linked_list.dart" - /* Вставить узел P после узла n0 в связном списке */ + /* Вставка узла P в связный список после узла n0 */ void insert(ListNode n0, ListNode P) { ListNode? n1 = n0.next; P.next = n1; @@ -537,7 +537,7 @@ comments: true === "Rust" ```rust title="linked_list.rs" - /* Вставить узел P после узла n0 в связном списке */ + /* Вставка узла P в связный список после узла n0 */ #[allow(non_snake_case)] pub fn insert(n0: &Rc>>, P: Rc>>) { let n1 = n0.borrow_mut().next.take(); @@ -549,7 +549,7 @@ comments: true === "C" ```c title="linked_list.c" - /* Вставить узел P после узла n0 в связном списке */ + /* Вставка узла P в связный список после узла n0 */ void insert(ListNode *n0, ListNode *P) { ListNode *n1 = n0->next; P->next = n1; @@ -560,7 +560,7 @@ comments: true === "Kotlin" ```kotlin title="linked_list.kt" - /* Вставить узел P после узла n0 в связном списке */ + /* Вставка узла P в связный список после узла n0 */ fun insert(n0: ListNode?, p: ListNode?) { val n1 = n0?.next p?.next = n1 @@ -571,7 +571,7 @@ comments: true === "Ruby" ```ruby title="linked_list.rb" - ### Вставка узла _p после узла n0 в связном списке ### + ### Вставка узла _p в связный список после узла n0 ### # В Ruby `p` является встроенной функцией, а `P` — константой, поэтому вместо них можно использовать `_p` def insert(n0, _p) n1 = n0.next @@ -582,8 +582,8 @@ comments: true ??? pythontutor "Визуализация кода" -
- +
+ ### 3.   Удаление узла @@ -599,7 +599,7 @@ comments: true ```python title="linked_list.py" def remove(n0: ListNode): - """Удалить первый узел после узла n0 в связном списке""" + """Удаление первого узла после узла n0 из связного списка""" if not n0.next: return # n0 -> P -> n1 @@ -611,7 +611,7 @@ comments: true === "C++" ```cpp title="linked_list.cpp" - /* Удалить первый узел после узла n0 в связном списке */ + /* Удаление первого узла после узла n0 из связного списка */ void remove(ListNode *n0) { if (n0->next == nullptr) return; @@ -627,7 +627,7 @@ comments: true === "Java" ```java title="linked_list.java" - /* Удалить первый узел после узла n0 в связном списке */ + /* Удаление первого узла после узла n0 из связного списка */ void remove(ListNode n0) { if (n0.next == null) return; @@ -641,7 +641,7 @@ comments: true === "C#" ```csharp title="linked_list.cs" - /* Удалить первый узел после узла n0 в связном списке */ + /* Удаление первого узла после узла n0 из связного списка */ void Remove(ListNode n0) { if (n0.next == null) return; @@ -655,7 +655,7 @@ comments: true === "Go" ```go title="linked_list.go" - /* Удалить первый узел после узла n0 в связном списке */ + /* Удаление первого узла после узла n0 из связного списка */ func removeItem(n0 *ListNode) { if n0.Next == nil { return @@ -670,7 +670,7 @@ comments: true === "Swift" ```swift title="linked_list.swift" - /* Удалить первый узел после узла n0 в связном списке */ + /* Удаление первого узла после узла n0 из связного списка */ func remove(n0: ListNode) { if n0.next == nil { return @@ -685,7 +685,7 @@ comments: true === "JS" ```javascript title="linked_list.js" - /* Удалить первый узел после узла n0 в связном списке */ + /* Удаление первого узла после узла n0 из связного списка */ function remove(n0) { if (!n0.next) return; // n0 -> P -> n1 @@ -698,7 +698,7 @@ comments: true === "TS" ```typescript title="linked_list.ts" - /* Удалить первый узел после узла n0 в связном списке */ + /* Удаление первого узла после узла n0 из связного списка */ function remove(n0: ListNode): void { if (!n0.next) { return; @@ -713,7 +713,7 @@ comments: true === "Dart" ```dart title="linked_list.dart" - /* Удалить первый узел после узла n0 в связном списке */ + /* Удаление первого узла после узла n0 из связного списка */ void remove(ListNode n0) { if (n0.next == null) return; // n0 -> P -> n1 @@ -726,7 +726,7 @@ comments: true === "Rust" ```rust title="linked_list.rs" - /* Удалить первый узел после узла n0 в связном списке */ + /* Удаление первого узла после узла n0 из связного списка */ #[allow(non_snake_case)] pub fn remove(n0: &Rc>>) { // n0 -> P -> n1 @@ -741,7 +741,7 @@ comments: true === "C" ```c title="linked_list.c" - /* Удалить первый узел после узла n0 в связном списке */ + /* Удаление первого узла после узла n0 из связного списка */ // Внимание: stdio.h уже использует ключевое слово remove void removeItem(ListNode *n0) { if (!n0->next) @@ -758,7 +758,7 @@ comments: true === "Kotlin" ```kotlin title="linked_list.kt" - /* Удалить первый узел после узла n0 в связном списке */ + /* Удаление первого узла после узла n0 из связного списка */ fun remove(n0: ListNode?) { if (n0?.next == null) return @@ -772,7 +772,7 @@ comments: true === "Ruby" ```ruby title="linked_list.rb" - ### Удаление первого узла после узла n0 в связном списке ### + ### Удаление первого узла после узла n0 из связного списка ### def remove(n0) return if n0.next.nil? @@ -785,8 +785,8 @@ comments: true ??? pythontutor "Визуализация кода" -
- +
+ ### 4.   Доступ к узлу @@ -796,7 +796,7 @@ comments: true ```python title="linked_list.py" def access(head: ListNode, index: int) -> ListNode | None: - """Доступ к узлу связного списка по индексу index""" + """Доступ к узлу с индексом index в связном списке""" for _ in range(index): if not head: return None @@ -807,7 +807,7 @@ comments: true === "C++" ```cpp title="linked_list.cpp" - /* Доступ к узлу связного списка по индексу index */ + /* Доступ к узлу с индексом index в связном списке */ ListNode *access(ListNode *head, int index) { for (int i = 0; i < index; i++) { if (head == nullptr) @@ -821,7 +821,7 @@ comments: true === "Java" ```java title="linked_list.java" - /* Доступ к узлу связного списка по индексу index */ + /* Доступ к узлу с индексом index в связном списке */ ListNode access(ListNode head, int index) { for (int i = 0; i < index; i++) { if (head == null) @@ -835,7 +835,7 @@ comments: true === "C#" ```csharp title="linked_list.cs" - /* Доступ к узлу связного списка по индексу index */ + /* Доступ к узлу с индексом index в связном списке */ ListNode? Access(ListNode? head, int index) { for (int i = 0; i < index; i++) { if (head == null) @@ -849,7 +849,7 @@ comments: true === "Go" ```go title="linked_list.go" - /* Доступ к узлу связного списка по индексу index */ + /* Доступ к узлу с индексом index в связном списке */ func access(head *ListNode, index int) *ListNode { for i := 0; i < index; i++ { if head == nil { @@ -864,7 +864,7 @@ comments: true === "Swift" ```swift title="linked_list.swift" - /* Доступ к узлу связного списка по индексу index */ + /* Доступ к узлу с индексом index в связном списке */ func access(head: ListNode, index: Int) -> ListNode? { var head: ListNode? = head for _ in 0 ..< index { @@ -880,7 +880,7 @@ comments: true === "JS" ```javascript title="linked_list.js" - /* Доступ к узлу связного списка по индексу index */ + /* Доступ к узлу с индексом index в связном списке */ function access(head, index) { for (let i = 0; i < index; i++) { if (!head) { @@ -895,7 +895,7 @@ comments: true === "TS" ```typescript title="linked_list.ts" - /* Доступ к узлу связного списка по индексу index */ + /* Доступ к узлу с индексом index в связном списке */ function access(head: ListNode | null, index: number): ListNode | null { for (let i = 0; i < index; i++) { if (!head) { @@ -910,7 +910,7 @@ comments: true === "Dart" ```dart title="linked_list.dart" - /* Доступ к узлу связного списка по индексу index */ + /* Доступ к узлу с индексом index в связном списке */ ListNode? access(ListNode? head, int index) { for (var i = 0; i < index; i++) { if (head == null) return null; @@ -923,7 +923,7 @@ comments: true === "Rust" ```rust title="linked_list.rs" - /* Доступ к узлу связного списка по индексу index */ + /* Доступ к узлу с индексом index в связном списке */ pub fn access(head: Rc>>, index: i32) -> Option>>> { fn dfs( head: Option<&Rc>>>, @@ -947,7 +947,7 @@ comments: true === "C" ```c title="linked_list.c" - /* Доступ к узлу связного списка по индексу index */ + /* Доступ к узлу с индексом index в связном списке */ ListNode *access(ListNode *head, int index) { for (int i = 0; i < index; i++) { if (head == NULL) @@ -961,7 +961,7 @@ comments: true === "Kotlin" ```kotlin title="linked_list.kt" - /* Доступ к узлу связного списка по индексу index */ + /* Доступ к узлу с индексом index в связном списке */ fun access(head: ListNode?, index: Int): ListNode? { var h = head for (i in 0.. - +
+ ### 5.   Поиск узла @@ -1000,7 +1000,7 @@ comments: true ```python title="linked_list.py" def find(head: ListNode, target: int) -> int: - """Найти в связном списке первый узел со значением target""" + """Поиск первого узла со значением target в связном списке""" index = 0 while head: if head.val == target: @@ -1013,7 +1013,7 @@ comments: true === "C++" ```cpp title="linked_list.cpp" - /* Найти в связном списке первый узел со значением target */ + /* Поиск первого узла со значением target в связном списке */ int find(ListNode *head, int target) { int index = 0; while (head != nullptr) { @@ -1029,7 +1029,7 @@ comments: true === "Java" ```java title="linked_list.java" - /* Найти в связном списке первый узел со значением target */ + /* Поиск первого узла со значением target в связном списке */ int find(ListNode head, int target) { int index = 0; while (head != null) { @@ -1045,7 +1045,7 @@ comments: true === "C#" ```csharp title="linked_list.cs" - /* Найти в связном списке первый узел со значением target */ + /* Поиск первого узла со значением target в связном списке */ int Find(ListNode? head, int target) { int index = 0; while (head != null) { @@ -1061,7 +1061,7 @@ comments: true === "Go" ```go title="linked_list.go" - /* Найти в связном списке первый узел со значением target */ + /* Поиск первого узла со значением target в связном списке */ func findNode(head *ListNode, target int) int { index := 0 for head != nil { @@ -1078,7 +1078,7 @@ comments: true === "Swift" ```swift title="linked_list.swift" - /* Найти в связном списке первый узел со значением target */ + /* Поиск первого узла со значением target в связном списке */ func find(head: ListNode, target: Int) -> Int { var head: ListNode? = head var index = 0 @@ -1096,7 +1096,7 @@ comments: true === "JS" ```javascript title="linked_list.js" - /* Найти в связном списке первый узел со значением target */ + /* Поиск первого узла со значением target в связном списке */ function find(head, target) { let index = 0; while (head !== null) { @@ -1113,7 +1113,7 @@ comments: true === "TS" ```typescript title="linked_list.ts" - /* Найти в связном списке первый узел со значением target */ + /* Поиск первого узла со значением target в связном списке */ function find(head: ListNode | null, target: number): number { let index = 0; while (head !== null) { @@ -1130,7 +1130,7 @@ comments: true === "Dart" ```dart title="linked_list.dart" - /* Найти в связном списке первый узел со значением target */ + /* Поиск первого узла со значением target в связном списке */ int find(ListNode? head, int target) { int index = 0; while (head != null) { @@ -1147,7 +1147,7 @@ comments: true === "Rust" ```rust title="linked_list.rs" - /* Найти в связном списке первый узел со значением target */ + /* Поиск первого узла со значением target в связном списке */ pub fn find(head: Rc>>, target: T) -> i32 { fn find(head: Option<&Rc>>>, target: T, idx: i32) -> i32 { if let Some(node) = head { @@ -1167,7 +1167,7 @@ comments: true === "C" ```c title="linked_list.c" - /* Найти в связном списке первый узел со значением target */ + /* Поиск первого узла со значением target в связном списке */ int find(ListNode *head, int target) { int index = 0; while (head) { @@ -1183,7 +1183,7 @@ comments: true === "Kotlin" ```kotlin title="linked_list.kt" - /* Найти в связном списке первый узел со значением target */ + /* Поиск первого узла со значением target в связном списке */ fun find(head: ListNode?, target: Int): Int { var index = 0 var h = head @@ -1215,8 +1215,8 @@ comments: true ??? pythontutor "Визуализация кода" -
- +
+ ## 4.2.2   Сравнение массива и связного списка @@ -1237,7 +1237,7 @@ comments: true -## 4.2.3   Основные типы связных списков +## 4.2.3   Распространенные типы связных списков Как показано на рисунке 4-8, существует три распространенных типа связных списков. @@ -1301,7 +1301,7 @@ comments: true Prev *DoublyListNode // Указатель на предыдущий узел } - // NewDoublyListNode Инициализация + // NewDoublyListNode инициализирует узел двусвязного списка. func NewDoublyListNode(val int) *DoublyListNode { return &DoublyListNode{ Val: val, @@ -1443,9 +1443,9 @@ comments: true end ``` -![Виды связных списков](linked_list.assets/linkedlist_common_types.png){ class="animation-figure" } +![Распространенные типы связных списков](linked_list.assets/linkedlist_common_types.png){ class="animation-figure" } -

Рисунок 4-8   Виды связных списков

+

Рисунок 4-8   Распространенные типы связных списков

## 4.2.4   Типичные применения связных списков diff --git a/ru/docs/chapter_array_and_linkedlist/list.md b/ru/docs/chapter_array_and_linkedlist/list.md index 10c6952e9..03aae5839 100644 --- a/ru/docs/chapter_array_and_linkedlist/list.md +++ b/ru/docs/chapter_array_and_linkedlist/list.md @@ -35,7 +35,7 @@ comments: true ```cpp title="list.cpp" /* Инициализация списка */ - // Обрати внимание: в C++ vector соответствует описываемому здесь nums + // Обратите внимание: в C++ vector соответствует описываемому здесь nums // Без начальных значений vector nums1; // С начальными значениями @@ -48,7 +48,7 @@ comments: true /* Инициализация списка */ // Без начальных значений List nums1 = new ArrayList<>(); - // С начальными значениями (обрати внимание: элементы массива должны использовать обертку Integer[] вместо int[]) + // С начальными значениями (обратите внимание: элементы массива должны использовать обертку Integer[] вместо int[]) Integer[] numbers = new Integer[] { 1, 3, 2, 5, 4 }; List nums = new ArrayList<>(Arrays.asList(numbers)); ``` @@ -158,7 +158,7 @@ comments: true ### 2.   Доступ к элементам -Поскольку в этом разделе список рассматривается как структура на основе динамического массива, доступ к элементам и их обновление можно выполнять за $O(1)$ времени, что очень эффективно. +Поскольку в этом разделе список рассматривается как структура на основе динамического массива, доступ к элементам и изменение их значений можно выполнять за $O(1)$ времени, что очень эффективно. === "Python" @@ -166,8 +166,8 @@ comments: true # Доступ к элементу num: int = nums[1] # Доступ к элементу по индексу 1 - # Обновление элемента - nums[1] = 0 # Обновить элемент по индексу 1 значением 0 + # Изменение элемента + nums[1] = 0 # Изменить значение элемента с индексом 1 на 0 ``` === "C++" @@ -176,8 +176,8 @@ comments: true /* Доступ к элементу */ int num = nums[1]; // Доступ к элементу по индексу 1 - /* Обновление элемента */ - nums[1] = 0; // Обновить элемент по индексу 1 значением 0 + /* Изменение элемента */ + nums[1] = 0; // Изменить значение элемента с индексом 1 на 0 ``` === "Java" @@ -186,8 +186,8 @@ comments: true /* Доступ к элементу */ int num = nums.get(1); // Доступ к элементу по индексу 1 - /* Обновление элемента */ - nums.set(1, 0); // Обновить элемент по индексу 1 значением 0 + /* Изменение элемента */ + nums.set(1, 0); // Изменить значение элемента с индексом 1 на 0 ``` === "C#" @@ -196,8 +196,8 @@ comments: true /* Доступ к элементу */ int num = nums[1]; // Доступ к элементу по индексу 1 - /* Обновление элемента */ - nums[1] = 0; // Обновить элемент по индексу 1 значением 0 + /* Изменение элемента */ + nums[1] = 0; // Изменить значение элемента с индексом 1 на 0 ``` === "Go" @@ -206,8 +206,8 @@ comments: true /* Доступ к элементу */ num := nums[1] // Доступ к элементу по индексу 1 - /* Обновление элемента */ - nums[1] = 0 // Обновить элемент по индексу 1 значением 0 + /* Изменение элемента */ + nums[1] = 0 // Изменить значение элемента с индексом 1 на 0 ``` === "Swift" @@ -216,8 +216,8 @@ comments: true /* Доступ к элементу */ let num = nums[1] // Доступ к элементу по индексу 1 - /* Обновление элемента */ - nums[1] = 0 // Обновить элемент по индексу 1 значением 0 + /* Изменение элемента */ + nums[1] = 0 // Изменить значение элемента с индексом 1 на 0 ``` === "JS" @@ -226,8 +226,8 @@ comments: true /* Доступ к элементу */ const num = nums[1]; // Доступ к элементу по индексу 1 - /* Обновление элемента */ - nums[1] = 0; // Обновить элемент по индексу 1 значением 0 + /* Изменение элемента */ + nums[1] = 0; // Изменить значение элемента с индексом 1 на 0 ``` === "TS" @@ -236,8 +236,8 @@ comments: true /* Доступ к элементу */ const num: number = nums[1]; // Доступ к элементу по индексу 1 - /* Обновление элемента */ - nums[1] = 0; // Обновить элемент по индексу 1 значением 0 + /* Изменение элемента */ + nums[1] = 0; // Изменить значение элемента с индексом 1 на 0 ``` === "Dart" @@ -246,8 +246,8 @@ comments: true /* Доступ к элементу */ int num = nums[1]; // Доступ к элементу по индексу 1 - /* Обновление элемента */ - nums[1] = 0; // Обновить элемент по индексу 1 значением 0 + /* Изменение элемента */ + nums[1] = 0; // Изменить значение элемента с индексом 1 на 0 ``` === "Rust" @@ -255,8 +255,8 @@ comments: true ```rust title="list.rs" /* Доступ к элементу */ let num: i32 = nums[1]; // Доступ к элементу по индексу 1 - /* Обновление элемента */ - nums[1] = 0; // Обновить элемент по индексу 1 значением 0 + /* Изменение элемента */ + nums[1] = 0; // Изменить значение элемента с индексом 1 на 0 ``` === "C" @@ -270,8 +270,8 @@ comments: true ```kotlin title="list.kt" /* Доступ к элементу */ val num = nums[1] // Доступ к элементу по индексу 1 - /* Обновление элемента */ - nums[1] = 0 // Обновить элемент по индексу 1 значением 0 + /* Изменение элемента */ + nums[1] = 0 // Изменить значение элемента с индексом 1 на 0 ``` === "Ruby" @@ -279,14 +279,14 @@ comments: true ```ruby title="list.rb" # Доступ к элементу num = nums[1] # Доступ к элементу по индексу 1 - # Обновление элемента - nums[1] = 0 # Обновить элемент по индексу 1 значением 0 + # Изменение элемента + nums[1] = 0 # Изменить значение элемента с индексом 1 на 0 ``` ??? pythontutor "Визуализация выполнения" -
- +
+ ### 3.   Вставка и удаление элементов @@ -953,8 +953,8 @@ comments: true ??? pythontutor "Визуализация выполнения" -
- +
+ ## 4.3.2   Реализация списка @@ -995,7 +995,7 @@ comments: true return self._arr[index] def set(self, num: int, index: int): - """Обновление элемента""" + """Изменение элемента""" if index < 0 or index >= self._size: raise IndexError("индекс выходит за границы") self._arr[index] = num @@ -1015,7 +1015,7 @@ comments: true # При превышении вместимости по числу элементов запускается расширение if self._size == self.capacity(): self.extend_capacity() - # Сдвинуть элемент с индексом index и все следующие элементы на одну позицию назад + # Сдвинуть элемент с индексом index и все следующие элементы на одну позицию вправо for j in range(self._size - 1, index - 1, -1): self._arr[j + 1] = self._arr[j] self._arr[index] = num @@ -1027,7 +1027,7 @@ comments: true if index < 0 or index >= self._size: raise IndexError("индекс выходит за границы") num = self._arr[index] - # Сдвинуть все элементы после индекса index на одну позицию вперед + # Сдвинуть все элементы после индекса index на одну позицию влево for j in range(index, self._size - 1): self._arr[j] = self._arr[j + 1] # Обновить число элементов @@ -1087,7 +1087,7 @@ comments: true return arr[index]; } - /* Обновление элемента */ + /* Изменение элемента */ void set(int index, int num) { if (index < 0 || index >= size()) throw out_of_range("индекс выходит за границы"); @@ -1111,7 +1111,7 @@ comments: true // При превышении вместимости по числу элементов запускается расширение if (size() == capacity()) extendCapacity(); - // Сдвинуть элемент с индексом index и все следующие элементы на одну позицию назад + // Сдвинуть элемент с индексом index и все следующие элементы на одну позицию вправо for (int j = size() - 1; j >= index; j--) { arr[j + 1] = arr[j]; } @@ -1125,7 +1125,7 @@ comments: true if (index < 0 || index >= size()) throw out_of_range("индекс выходит за границы"); int num = arr[index]; - // Сдвинуть все элементы после индекса index на одну позицию вперед + // Сдвинуть все элементы после индекса index на одну позицию влево for (int j = index; j < size() - 1; j++) { arr[j] = arr[j + 1]; } @@ -1195,7 +1195,7 @@ comments: true return arr[index]; } - /* Обновление элемента */ + /* Изменение элемента */ public void set(int index, int num) { if (index < 0 || index >= size) throw new IndexOutOfBoundsException("индекс выходит за границы"); @@ -1219,7 +1219,7 @@ comments: true // При превышении вместимости по числу элементов запускается расширение if (size == capacity()) extendCapacity(); - // Сдвинуть элемент с индексом index и все следующие элементы на одну позицию назад + // Сдвинуть элемент с индексом index и все следующие элементы на одну позицию вправо for (int j = size - 1; j >= index; j--) { arr[j + 1] = arr[j]; } @@ -1233,7 +1233,7 @@ comments: true if (index < 0 || index >= size) throw new IndexOutOfBoundsException("индекс выходит за границы"); int num = arr[index]; - // Сдвинуть все элементы после индекса index на одну позицию вперед + // Сдвинуть все элементы после индекса index на одну позицию влево for (int j = index; j < size - 1; j++) { arr[j] = arr[j + 1]; } @@ -1297,7 +1297,7 @@ comments: true return arr[index]; } - /* Обновление элемента */ + /* Изменение элемента */ public void Set(int index, int num) { if (index < 0 || index >= arrSize) throw new IndexOutOfRangeException("индекс выходит за границы"); @@ -1321,7 +1321,7 @@ comments: true // При превышении вместимости по числу элементов запускается расширение if (arrSize == arrCapacity) ExtendCapacity(); - // Сдвинуть элемент с индексом index и все следующие элементы на одну позицию назад + // Сдвинуть элемент с индексом index и все следующие элементы на одну позицию вправо for (int j = arrSize - 1; j >= index; j--) { arr[j + 1] = arr[j]; } @@ -1335,7 +1335,7 @@ comments: true if (index < 0 || index >= arrSize) throw new IndexOutOfRangeException("индекс выходит за границы"); int num = arr[index]; - // Сдвинуть все элементы после индекса index на одну позицию вперед + // Сдвинуть все элементы после индекса index на одну позицию влево for (int j = index; j < arrSize - 1; j++) { arr[j] = arr[j + 1]; } @@ -1405,7 +1405,7 @@ comments: true return l.arr[index] } - /* Обновление элемента */ + /* Изменение элемента */ func (l *myList) set(num, index int) { if index < 0 || index >= l.arrSize { panic("индекс выходит за границы") @@ -1433,7 +1433,7 @@ comments: true if l.arrSize == l.arrCapacity { l.extendCapacity() } - // Сдвинуть элемент с индексом index и все следующие элементы на одну позицию назад + // Сдвинуть элемент с индексом index и все следующие элементы на одну позицию вправо for j := l.arrSize - 1; j >= index; j-- { l.arr[j+1] = l.arr[j] } @@ -1448,7 +1448,7 @@ comments: true panic("индекс выходит за границы") } num := l.arr[index] - // Сдвинуть все элементы после индекса index на одну позицию вперед + // Сдвинуть все элементы после индекса index на одну позицию влево for j := index; j < l.arrSize-1; j++ { l.arr[j] = l.arr[j+1] } @@ -1510,7 +1510,7 @@ comments: true return arr[index] } - /* Обновление элемента */ + /* Изменение элемента */ func set(index: Int, num: Int) { if index < 0 || index >= size() { fatalError("индекс выходит за границы") @@ -1538,7 +1538,7 @@ comments: true if size() == capacity() { extendCapacity() } - // Сдвинуть элемент с индексом index и все следующие элементы на одну позицию назад + // Сдвинуть элемент с индексом index и все следующие элементы на одну позицию вправо for j in (index ..< size()).reversed() { arr[j + 1] = arr[j] } @@ -1554,7 +1554,7 @@ comments: true fatalError("индекс выходит за границы") } let num = arr[index] - // Сдвинуть все элементы после индекса index на одну позицию вперед + // Сдвинуть все элементы после индекса index на одну позицию влево for j in index ..< (size() - 1) { arr[j] = arr[j + 1] } @@ -1611,7 +1611,7 @@ comments: true return this.#arr[index]; } - /* Обновление элемента */ + /* Изменение элемента */ set(index, num) { if (index < 0 || index >= this.#size) throw new Error('индекс выходит за границы'); this.#arr[index] = num; @@ -1635,7 +1635,7 @@ comments: true if (this.#size === this.#capacity) { this.extendCapacity(); } - // Сдвинуть элемент с индексом index и все следующие элементы на одну позицию назад + // Сдвинуть элемент с индексом index и все следующие элементы на одну позицию вправо for (let j = this.#size - 1; j >= index; j--) { this.#arr[j + 1] = this.#arr[j]; } @@ -1648,7 +1648,7 @@ comments: true remove(index) { if (index < 0 || index >= this.#size) throw new Error('индекс выходит за границы'); let num = this.#arr[index]; - // Сдвинуть все элементы после индекса index на одну позицию вперед + // Сдвинуть все элементы после индекса index на одну позицию влево for (let j = index; j < this.#size - 1; j++) { this.#arr[j] = this.#arr[j + 1]; } @@ -1713,7 +1713,7 @@ comments: true return this.arr[index]; } - /* Обновление элемента */ + /* Изменение элемента */ public set(index: number, num: number): void { if (index < 0 || index >= this._size) throw new Error('индекс выходит за границы'); this.arr[index] = num; @@ -1735,7 +1735,7 @@ comments: true if (this._size === this._capacity) { this.extendCapacity(); } - // Сдвинуть элемент с индексом index и все следующие элементы на одну позицию назад + // Сдвинуть элемент с индексом index и все следующие элементы на одну позицию вправо for (let j = this._size - 1; j >= index; j--) { this.arr[j + 1] = this.arr[j]; } @@ -1748,7 +1748,7 @@ comments: true public remove(index: number): number { if (index < 0 || index >= this._size) throw new Error('индекс выходит за границы'); let num = this.arr[index]; - // Сдвинуть все элементы после индекса index на одну позицию вперед + // Сдвинуть все элементы после индекса index на одну позицию влево for (let j = index; j < this._size - 1; j++) { this.arr[j] = this.arr[j + 1]; } @@ -1808,7 +1808,7 @@ comments: true return _arr[index]; } - /* Обновление элемента */ + /* Изменение элемента */ void set(int index, int _num) { if (index >= _size) throw RangeError('индекс выходит за границы'); _arr[index] = _num; @@ -1828,7 +1828,7 @@ comments: true if (index >= _size) throw RangeError('индекс выходит за границы'); // При превышении вместимости по числу элементов запускается расширение if (_size == _capacity) extendCapacity(); - // Сдвинуть элемент с индексом index и все следующие элементы на одну позицию назад + // Сдвинуть элемент с индексом index и все следующие элементы на одну позицию вправо for (var j = _size - 1; j >= index; j--) { _arr[j + 1] = _arr[j]; } @@ -1841,7 +1841,7 @@ comments: true int remove(int index) { if (index >= _size) throw RangeError('индекс выходит за границы'); int _num = _arr[index]; - // Сдвинуть все элементы после индекса index на одну позицию вперед + // Сдвинуть все элементы после индекса index на одну позицию влево for (var j = index; j < _size - 1; j++) { _arr[j] = _arr[j + 1]; } @@ -1918,7 +1918,7 @@ comments: true return self.arr[index]; } - /* Обновление элемента */ + /* Изменение элемента */ pub fn set(&mut self, index: usize, num: i32) { if index >= self.size { panic!("индекс выходит за границы") @@ -1946,7 +1946,7 @@ comments: true if self.size == self.capacity() { self.extend_capacity(); } - // Сдвинуть элемент с индексом index и все следующие элементы на одну позицию назад + // Сдвинуть элемент с индексом index и все следующие элементы на одну позицию вправо for j in (index..self.size).rev() { self.arr[j + 1] = self.arr[j]; } @@ -1961,7 +1961,7 @@ comments: true panic!("индекс выходит за границы") }; let num = self.arr[index]; - // Сдвинуть все элементы после индекса index на одну позицию вперед + // Сдвинуть все элементы после индекса index на одну позицию влево for j in index..self.size - 1 { self.arr[j] = self.arr[j + 1]; } @@ -2035,7 +2035,7 @@ comments: true return nums->arr[index]; } - /* Обновление элемента */ + /* Изменение элемента */ void set(MyList *nums, int index, int num) { assert(index >= 0 && index < nums->size); nums->arr[index] = num; @@ -2134,7 +2134,7 @@ comments: true return arr[index] } - /* Обновление элемента */ + /* Изменение элемента */ fun set(index: Int, num: Int) { if (index < 0 || index >= size) throw IndexOutOfBoundsException("индекс выходит за границы") @@ -2158,7 +2158,7 @@ comments: true // При превышении вместимости по числу элементов запускается расширение if (size == capacity()) extendCapacity() - // Сдвинуть элемент с индексом index и все следующие элементы на одну позицию назад + // Сдвинуть элемент с индексом index и все следующие элементы на одну позицию вправо for (j in size - 1 downTo index) arr[j + 1] = arr[j] arr[index] = num @@ -2171,7 +2171,7 @@ comments: true if (index < 0 || index >= size) throw IndexOutOfBoundsException("индекс выходит за границы") val num = arr[index] - // Сдвинуть все элементы после индекса index на одну позицию вперед + // Сдвинуть все элементы после индекса index на одну позицию влево for (j in index..= size num = @arr[index] - # Сдвинуть все элементы после индекса index на одну позицию вперед + # Сдвинуть все элементы после индекса index на одну позицию влево for j in index...size @arr[j] = @arr[j + 1] end diff --git a/ru/docs/chapter_array_and_linkedlist/ram_and_cache.md b/ru/docs/chapter_array_and_linkedlist/ram_and_cache.md index 3d709fc1c..fd3ef0cd8 100644 --- a/ru/docs/chapter_array_and_linkedlist/ram_and_cache.md +++ b/ru/docs/chapter_array_and_linkedlist/ram_and_cache.md @@ -20,9 +20,9 @@ comments: true | -------------- | --------------------------------------- | ----------------------------------------- | ------------------------------------------------------- | | Назначение | Долговременное хранение данных, включая ОС, программы, файлы и т.д. | Временное хранение выполняемых программ и обрабатываемых данных | Хранение часто используемых данных и инструкций, уменьшающее число обращений CPU к памяти | | Энергозависимость | Данные не теряются после отключения питания | Данные теряются после отключения питания | Данные теряются после отключения питания | -| Емкость | Большая, уровень TB | Меньшая, уровень GB | Очень малая, уровень MB | +| Емкость | Большая, на уровне TB | Меньшая, на уровне GB | Очень малая, на уровне MB | | Скорость | Низкая, от сотен до тысяч MB/s | Высокая, десятки GB/s | Очень высокая, десятки и сотни GB/s | -| Цена | Низкая, единицы валюты за GB | Высокая, десятки и сотни валютных единиц за GB | Очень высокая, входит в стоимость CPU | +| Цена (в китайских юанях) | Низкая, от нескольких десятых долей юаня до нескольких юаней за GB | Высокая, десятки и сотни юаней за GB | Очень высокая, входит в стоимость CPU | diff --git a/ru/docs/chapter_data_structure/basic_data_types.md b/ru/docs/chapter_data_structure/basic_data_types.md index 1eb9f13a5..7f01cc392 100644 --- a/ru/docs/chapter_data_structure/basic_data_types.md +++ b/ru/docs/chapter_data_structure/basic_data_types.md @@ -39,7 +39,7 @@ comments: true -Обрати внимание: в таблице 3-1 приведены данные именно для базовых типов данных Java. В каждом языке программирования свои определения типов, поэтому объем памяти, диапазон значений и значения по умолчанию могут различаться. +Обратите внимание: в таблице 3-1 приведены данные именно для базовых типов данных Java. В каждом языке программирования свои определения типов, поэтому объем памяти, диапазон значений и значения по умолчанию могут различаться. - В Python целочисленный тип `int` может иметь произвольный размер, ограниченный только доступной памятью. Тип `float` является 64-битным числом двойной точности. Типа `char` нет, а отдельный символ на деле является строкой `str` длины 1. - В C и C++ размер базовых типов данных явно не зафиксирован и зависит от реализации и платформы. В таблице 3-1 приведены данные для модели LP64 [data model](https://en.cppreference.com/w/cpp/language/types#Properties), используемой в 64-битных Unix-системах, включая Linux и macOS. diff --git a/ru/docs/chapter_data_structure/number_encoding.md b/ru/docs/chapter_data_structure/number_encoding.md index ecae42736..a2c83f1a3 100644 --- a/ru/docs/chapter_data_structure/number_encoding.md +++ b/ru/docs/chapter_data_structure/number_encoding.md @@ -86,7 +86,7 @@ $$ Ты, вероятно, уже заметил, что все приведенные выше вычисления были операциями сложения. Это указывает на важный факт: **аппаратные схемы внутри компьютера в основном проектируются на основе операций сложения**. Причина в том, что сложение по сравнению с другими операциями (например умножением, делением и вычитанием) проще реализуется на аппаратном уровне, легче распараллеливается и выполняется быстрее. -Обрати внимание: это не означает, что компьютер умеет только складывать. **Комбинируя сложение с некоторыми базовыми логическими операциями, компьютер может реализовать и другие математические операции**. Например, вычитание $a - b$ можно преобразовать в сложение $a + (-b)$. Умножение и деление можно свести к многократному сложению или вычитанию. +Обратите внимание: это не означает, что компьютер умеет только складывать. **Комбинируя сложение с некоторыми базовыми логическими операциями, компьютер может реализовать и другие математические операции**. Например, вычитание $a - b$ можно преобразовать в сложение $a + (-b)$. Умножение и деление можно свести к многократному сложению или вычитанию. Теперь можно подвести итог, почему компьютеры используют дополнительный код: с представлением в дополнительном коде компьютер может использовать одни и те же схемы и операции для сложения положительных и отрицательных чисел, без необходимости проектировать специальные аппаратные схемы для вычитания и без особой обработки неоднозначности положительного и отрицательного нуля. Это значительно упрощает аппаратную архитектуру и повышает эффективность вычислений. diff --git a/ru/docs/chapter_divide_and_conquer/binary_search_recur.md b/ru/docs/chapter_divide_and_conquer/binary_search_recur.md index f1938d04d..44b019d23 100644 --- a/ru/docs/chapter_divide_and_conquer/binary_search_recur.md +++ b/ru/docs/chapter_divide_and_conquer/binary_search_recur.md @@ -50,7 +50,7 @@ comments: true ```python title="binary_search_recur.py" def dfs(nums: list[int], target: int, i: int, j: int) -> int: - """Бинарный поиск: задача f(i, j)""" + """Двоичный поиск: задача f(i, j)""" # Если интервал пуст, целевой элемент отсутствует, вернуть -1 if i > j: return -1 @@ -67,7 +67,7 @@ comments: true return m def binary_search(nums: list[int], target: int) -> int: - """Бинарный поиск""" + """Двоичный поиск""" n = len(nums) # Решить задачу f(0, n-1) return dfs(nums, target, 0, n - 1) @@ -76,7 +76,7 @@ comments: true === "C++" ```cpp title="binary_search_recur.cpp" - /* Бинарный поиск: задача f(i, j) */ + /* Двоичный поиск: задача f(i, j) */ int dfs(vector &nums, int target, int i, int j) { // Если интервал пуст, целевой элемент отсутствует, вернуть -1 if (i > j) { @@ -96,7 +96,7 @@ comments: true } } - /* Бинарный поиск */ + /* Двоичный поиск */ int binarySearch(vector &nums, int target) { int n = nums.size(); // Решить задачу f(0, n-1) @@ -107,7 +107,7 @@ comments: true === "Java" ```java title="binary_search_recur.java" - /* Бинарный поиск: задача f(i, j) */ + /* Двоичный поиск: задача f(i, j) */ int dfs(int[] nums, int target, int i, int j) { // Если интервал пуст, целевой элемент отсутствует, вернуть -1 if (i > j) { @@ -127,7 +127,7 @@ comments: true } } - /* Бинарный поиск */ + /* Двоичный поиск */ int binarySearch(int[] nums, int target) { int n = nums.length; // Решить задачу f(0, n-1) @@ -138,7 +138,7 @@ comments: true === "C#" ```csharp title="binary_search_recur.cs" - /* Бинарный поиск: задача f(i, j) */ + /* Двоичный поиск: задача f(i, j) */ int DFS(int[] nums, int target, int i, int j) { // Если интервал пуст, целевой элемент отсутствует, вернуть -1 if (i > j) { @@ -158,7 +158,7 @@ comments: true } } - /* Бинарный поиск */ + /* Двоичный поиск */ int BinarySearch(int[] nums, int target) { int n = nums.Length; // Решить задачу f(0, n-1) @@ -169,7 +169,7 @@ comments: true === "Go" ```go title="binary_search_recur.go" - /* Бинарный поиск: задача f(i, j) */ + /* Двоичный поиск: задача f(i, j) */ func dfs(nums []int, target, i, j int) int { // Если интервал пуст, это означает отсутствие целевого элемента, вернуть -1 if i > j { @@ -192,7 +192,7 @@ comments: true } } - /* Бинарный поиск */ + /* Двоичный поиск */ func binarySearch(nums []int, target int) int { n := len(nums) return dfs(nums, target, 0, n-1) @@ -202,7 +202,7 @@ comments: true === "Swift" ```swift title="binary_search_recur.swift" - /* Бинарный поиск: задача f(i, j) */ + /* Двоичный поиск: задача f(i, j) */ func dfs(nums: [Int], target: Int, i: Int, j: Int) -> Int { // Если интервал пуст, целевой элемент отсутствует, вернуть -1 if i > j { @@ -222,7 +222,7 @@ comments: true } } - /* Бинарный поиск */ + /* Двоичный поиск */ func binarySearch(nums: [Int], target: Int) -> Int { // Решить задачу f(0, n-1) dfs(nums: nums, target: target, i: nums.startIndex, j: nums.endIndex - 1) @@ -232,7 +232,7 @@ comments: true === "JS" ```javascript title="binary_search_recur.js" - /* Бинарный поиск: задача f(i, j) */ + /* Двоичный поиск: задача f(i, j) */ function dfs(nums, target, i, j) { // Если интервал пуст, целевой элемент отсутствует, вернуть -1 if (i > j) { @@ -252,7 +252,7 @@ comments: true } } - /* Бинарный поиск */ + /* Двоичный поиск */ function binarySearch(nums, target) { const n = nums.length; // Решить задачу f(0, n-1) @@ -263,7 +263,7 @@ comments: true === "TS" ```typescript title="binary_search_recur.ts" - /* Бинарный поиск: задача f(i, j) */ + /* Двоичный поиск: задача f(i, j) */ function dfs(nums: number[], target: number, i: number, j: number): number { // Если интервал пуст, целевой элемент отсутствует, вернуть -1 if (i > j) { @@ -283,7 +283,7 @@ comments: true } } - /* Бинарный поиск */ + /* Двоичный поиск */ function binarySearch(nums: number[], target: number): number { const n = nums.length; // Решить задачу f(0, n-1) @@ -294,7 +294,7 @@ comments: true === "Dart" ```dart title="binary_search_recur.dart" - /* Бинарный поиск: задача f(i, j) */ + /* Двоичный поиск: задача f(i, j) */ int dfs(List nums, int target, int i, int j) { // Если интервал пуст, целевой элемент отсутствует, вернуть -1 if (i > j) { @@ -314,7 +314,7 @@ comments: true } } - /* Бинарный поиск */ + /* Двоичный поиск */ int binarySearch(List nums, int target) { int n = nums.length; // Решить задачу f(0, n-1) @@ -325,7 +325,7 @@ comments: true === "Rust" ```rust title="binary_search_recur.rs" - /* Бинарный поиск: задача f(i, j) */ + /* Двоичный поиск: задача f(i, j) */ fn dfs(nums: &[i32], target: i32, i: i32, j: i32) -> i32 { // Если интервал пуст, целевой элемент отсутствует, вернуть -1 if i > j { @@ -344,7 +344,7 @@ comments: true } } - /* Бинарный поиск */ + /* Двоичный поиск */ fn binary_search(nums: &[i32], target: i32) -> i32 { let n = nums.len() as i32; // Решить задачу f(0, n-1) @@ -355,7 +355,7 @@ comments: true === "C" ```c title="binary_search_recur.c" - /* Бинарный поиск: задача f(i, j) */ + /* Двоичный поиск: задача f(i, j) */ int dfs(int nums[], int target, int i, int j) { // Если интервал пуст, целевой элемент отсутствует, вернуть -1 if (i > j) { @@ -375,7 +375,7 @@ comments: true } } - /* Бинарный поиск */ + /* Двоичный поиск */ int binarySearch(int nums[], int target, int numsSize) { int n = numsSize; // Решить задачу f(0, n-1) @@ -386,7 +386,7 @@ comments: true === "Kotlin" ```kotlin title="binary_search_recur.kt" - /* Бинарный поиск: задача f(i, j) */ + /* Двоичный поиск: задача f(i, j) */ fun dfs( nums: IntArray, target: Int, @@ -411,7 +411,7 @@ comments: true } } - /* Бинарный поиск */ + /* Двоичный поиск */ fun binarySearch(nums: IntArray, target: Int): Int { val n = nums.size // Решить задачу f(0, n-1) @@ -422,7 +422,7 @@ comments: true === "Ruby" ```ruby title="binary_search_recur.rb" - ### Бинарный поиск: задача f(i, j) ### + ### Двоичный поиск: задача f(i, j) ### def dfs(nums, target, i, j) # Если интервал пуст, целевой элемент отсутствует, вернуть -1 return -1 if i > j @@ -442,7 +442,7 @@ comments: true end end - ### Бинарный поиск ### + ### Двоичный поиск ### def binary_search(nums, target) n = nums.length # Решить задачу f(0, n-1) @@ -452,5 +452,5 @@ comments: true ??? pythontutor "Визуализация кода" -
- +
+ diff --git a/ru/docs/chapter_hashing/hash_algorithm.md b/ru/docs/chapter_hashing/hash_algorithm.md index 98399706f..25827000f 100644 --- a/ru/docs/chapter_hashing/hash_algorithm.md +++ b/ru/docs/chapter_hashing/hash_algorithm.md @@ -41,7 +41,7 @@ index = hash(key) % capacity - **Устойчивость к коллизиям**: должно быть крайне трудно найти два разных входа, имеющих одинаковое хеш-значение. - **Эффект лавины**: даже небольшое изменение во входных данных должно приводить к заметному и непредсказуемому изменению результата. -Обрати внимание: **«равномерное распределение» и «устойчивость к коллизиям» - это два независимых понятия** , и выполнение первого не означает автоматического выполнения второго. Например, при случайном распределении входных `key` хеш-функция `key % 100` может выдавать достаточно равномерное распределение. Однако этот хеш-алгоритм слишком прост: все `key` с одинаковыми двумя последними цифрами будут иметь одинаковый результат, а значит, по хеш-значению можно легко подобрать подходящие `key` и, например, взломать пароль. +Обратите внимание: **«равномерное распределение» и «устойчивость к коллизиям» - это два независимых понятия** , и выполнение первого не означает автоматического выполнения второго. Например, при случайном распределении входных `key` хеш-функция `key % 100` может выдавать достаточно равномерное распределение. Однако этот хеш-алгоритм слишком прост: все `key` с одинаковыми двумя последними цифрами будут иметь одинаковый результат, а значит, по хеш-значению можно легко подобрать подходящие `key` и, например, взломать пароль. ## 6.3.2   Проектирование хеш-алгоритма @@ -712,7 +712,7 @@ $$ !!! tip - Обрати внимание: определения и способы вычисления встроенных хеш-значений в разных языках программирования отличаются. + Обратите внимание: определения и способы вычисления встроенных хеш-значений в разных языках программирования отличаются. === "Python" diff --git a/ru/docs/chapter_hashing/hash_collision.md b/ru/docs/chapter_hashing/hash_collision.md index 8cc7a8ba5..d419ef6c9 100644 --- a/ru/docs/chapter_hashing/hash_collision.md +++ b/ru/docs/chapter_hashing/hash_collision.md @@ -3307,7 +3307,7 @@ comments: true !!! tip - Обрати внимание: у хеш-таблиц с открытой адресацией (линейное пробирование, квадратичное пробирование и повторное хеширование) есть общая проблема: в них нельзя напрямую удалять элементы. + Обратите внимание: у хеш-таблиц с открытой адресацией (линейное пробирование, квадратичное пробирование и повторное хеширование) есть общая проблема: в них нельзя напрямую удалять элементы. ## 6.2.3   Выбор в языках программирования diff --git a/ru/docs/chapter_searching/binary_search.md b/ru/docs/chapter_searching/binary_search.md index 682acbda2..dedb886dc 100644 --- a/ru/docs/chapter_searching/binary_search.md +++ b/ru/docs/chapter_searching/binary_search.md @@ -57,8 +57,8 @@ comments: true ```python title="binary_search.py" def binary_search(nums: list[int], target: int) -> int: - """Бинарный поиск (двусторонне замкнутый интервал)""" - # Инициализировать двусторонне замкнутый интервал [0, n-1], то есть i и j указывают на первый и последний элементы массива соответственно + """Двоичный поиск (замкнутый интервал)""" + # Инициализировать замкнутый интервал [0, n-1], то есть i и j указывают на первый и последний элементы массива соответственно i, j = 0, len(nums) - 1 # Цикл завершается, когда диапазон поиска пуст (при i > j диапазон пуст) while i <= j: @@ -76,9 +76,9 @@ comments: true === "C++" ```cpp title="binary_search.cpp" - /* Бинарный поиск (двусторонне замкнутый интервал) */ + /* Двоичный поиск (замкнутый интервал) */ int binarySearch(vector &nums, int target) { - // Инициализировать двусторонне замкнутый интервал [0, n-1], то есть i и j указывают на первый и последний элементы массива соответственно + // Инициализировать замкнутый интервал [0, n-1], то есть i и j указывают на первый и последний элементы массива соответственно int i = 0, j = nums.size() - 1; // Цикл завершается, когда диапазон поиска пуст (при i > j диапазон пуст) while (i <= j) { @@ -98,9 +98,9 @@ comments: true === "Java" ```java title="binary_search.java" - /* Бинарный поиск (двусторонне замкнутый интервал) */ + /* Двоичный поиск (замкнутый интервал) */ int binarySearch(int[] nums, int target) { - // Инициализировать двусторонне замкнутый интервал [0, n-1], то есть i и j указывают на первый и последний элементы массива соответственно + // Инициализировать замкнутый интервал [0, n-1], то есть i и j указывают на первый и последний элементы массива соответственно int i = 0, j = nums.length - 1; // Цикл завершается, когда диапазон поиска пуст (при i > j диапазон пуст) while (i <= j) { @@ -120,9 +120,9 @@ comments: true === "C#" ```csharp title="binary_search.cs" - /* Бинарный поиск (двусторонне замкнутый интервал) */ + /* Двоичный поиск (замкнутый интервал) */ int BinarySearch(int[] nums, int target) { - // Инициализировать двусторонне замкнутый интервал [0, n-1], то есть i и j указывают на первый и последний элементы массива соответственно + // Инициализировать замкнутый интервал [0, n-1], то есть i и j указывают на первый и последний элементы массива соответственно int i = 0, j = nums.Length - 1; // Цикл завершается, когда диапазон поиска пуст (при i > j диапазон пуст) while (i <= j) { @@ -142,9 +142,9 @@ comments: true === "Go" ```go title="binary_search.go" - /* Бинарный поиск (двусторонне замкнутый интервал) */ + /* Двоичный поиск (замкнутый интервал) */ func binarySearch(nums []int, target int) int { - // Инициализировать двусторонне замкнутый интервал [0, n-1], то есть i и j указывают на первый и последний элементы массива соответственно + // Инициализировать замкнутый интервал [0, n-1], то есть i и j указывают на первый и последний элементы массива соответственно i, j := 0, len(nums)-1 // Цикл завершается, когда диапазон поиска пуст (при i > j диапазон пуст) for i <= j { @@ -165,9 +165,9 @@ comments: true === "Swift" ```swift title="binary_search.swift" - /* Бинарный поиск (двусторонне замкнутый интервал) */ + /* Двоичный поиск (замкнутый интервал) */ func binarySearch(nums: [Int], target: Int) -> Int { - // Инициализировать двусторонне замкнутый интервал [0, n-1], то есть i и j указывают на первый и последний элементы массива соответственно + // Инициализировать замкнутый интервал [0, n-1], то есть i и j указывают на первый и последний элементы массива соответственно var i = nums.startIndex var j = nums.endIndex - 1 // Цикл завершается, когда диапазон поиска пуст (при i > j диапазон пуст) @@ -189,9 +189,9 @@ comments: true === "JS" ```javascript title="binary_search.js" - /* Бинарный поиск (двусторонне замкнутый интервал) */ + /* Двоичный поиск (замкнутый интервал) */ function binarySearch(nums, target) { - // Инициализировать двусторонне замкнутый интервал [0, n-1], то есть i и j указывают на первый и последний элементы массива соответственно + // Инициализировать замкнутый интервал [0, n-1], то есть i и j указывают на первый и последний элементы массива соответственно let i = 0, j = nums.length - 1; // Цикл завершается, когда диапазон поиска пуст (при i > j диапазон пуст) @@ -214,9 +214,9 @@ comments: true === "TS" ```typescript title="binary_search.ts" - /* Бинарный поиск (двусторонне замкнутый интервал) */ + /* Двоичный поиск (замкнутый интервал) */ function binarySearch(nums: number[], target: number): number { - // Инициализировать двусторонне замкнутый интервал [0, n-1], то есть i и j указывают на первый и последний элементы массива соответственно + // Инициализировать замкнутый интервал [0, n-1], то есть i и j указывают на первый и последний элементы массива соответственно let i = 0, j = nums.length - 1; // Цикл завершается, когда диапазон поиска пуст (при i > j диапазон пуст) @@ -241,9 +241,9 @@ comments: true === "Dart" ```dart title="binary_search.dart" - /* Бинарный поиск (двусторонне замкнутый интервал) */ + /* Двоичный поиск (замкнутый интервал) */ int binarySearch(List nums, int target) { - // Инициализировать двусторонне замкнутый интервал [0, n-1], то есть i и j указывают на первый и последний элементы массива соответственно + // Инициализировать замкнутый интервал [0, n-1], то есть i и j указывают на первый и последний элементы массива соответственно int i = 0, j = nums.length - 1; // Цикл завершается, когда диапазон поиска пуст (при i > j диапазон пуст) while (i <= j) { @@ -267,9 +267,9 @@ comments: true === "Rust" ```rust title="binary_search.rs" - /* Бинарный поиск (двусторонне замкнутый интервал) */ + /* Двоичный поиск (замкнутый интервал) */ fn binary_search(nums: &[i32], target: i32) -> i32 { - // Инициализировать двусторонне замкнутый интервал [0, n-1], то есть i и j указывают на первый и последний элементы массива соответственно + // Инициализировать замкнутый интервал [0, n-1], то есть i и j указывают на первый и последний элементы массива соответственно let mut i = 0; let mut j = nums.len() as i32 - 1; // Цикл завершается, когда диапазон поиска пуст (при i > j диапазон пуст) @@ -294,9 +294,9 @@ comments: true === "C" ```c title="binary_search.c" - /* Бинарный поиск (двусторонне замкнутый интервал) */ + /* Двоичный поиск (замкнутый интервал) */ int binarySearch(int *nums, int len, int target) { - // Инициализировать двусторонне замкнутый интервал [0, n-1], то есть i и j указывают на первый и последний элементы массива соответственно + // Инициализировать замкнутый интервал [0, n-1], то есть i и j указывают на первый и последний элементы массива соответственно int i = 0, j = len - 1; // Цикл завершается, когда диапазон поиска пуст (при i > j диапазон пуст) while (i <= j) { @@ -316,9 +316,9 @@ comments: true === "Kotlin" ```kotlin title="binary_search.kt" - /* Бинарный поиск (двусторонне замкнутый интервал) */ + /* Двоичный поиск (замкнутый интервал) */ fun binarySearch(nums: IntArray, target: Int): Int { - // Инициализировать двусторонне замкнутый интервал [0, n-1], то есть i и j указывают на первый и последний элементы массива соответственно + // Инициализировать замкнутый интервал [0, n-1], то есть i и j указывают на первый и последний элементы массива соответственно var i = 0 var j = nums.size - 1 // Цикл завершается, когда диапазон поиска пуст (при i > j диапазон пуст) @@ -339,9 +339,9 @@ comments: true === "Ruby" ```ruby title="binary_search.rb" - ### Бинарный поиск (двусторонне замкнутый интервал) ### + ### Двоичный поиск (замкнутый интервал) ### def binary_search(nums, target) - # Инициализировать двусторонне замкнутый интервал [0, n-1], то есть i и j указывают на первый и последний элементы массива соответственно + # Инициализировать замкнутый интервал [0, n-1], то есть i и j указывают на первый и последний элементы массива соответственно i, j = 0, nums.length - 1 # Цикл завершается, когда диапазон поиска пуст (при i > j диапазон пуст) @@ -364,8 +364,8 @@ comments: true ??? pythontutor "Визуализация кода" -
- +
+ **Временная сложность равна $O(\log n)$** : в цикле двоичного поиска интервал каждый раз сокращается вдвое, поэтому число итераций равно $\log_2 n$ . @@ -373,7 +373,7 @@ comments: true ## 10.1.1   Методы представления интервалов -Помимо описанного выше двойного замкнутого интервала, часто используется и левозамкнутый правооткрытый интервал, который задается как $[0, n)$ , то есть левая граница включается, а правая - нет. В этом представлении интервал $[i, j)$ пуст, когда $i = j$ . +Помимо описанного выше замкнутого интервала, часто используется и полуинтервал $[0, n)$, замкнутый слева и открытый справа , то есть левая граница включается, а правая - нет. В этом представлении интервал $[i, j)$ пуст, когда $i = j$ . На основе этого представления можно реализовать двоичный поиск с той же функциональностью: @@ -381,8 +381,8 @@ comments: true ```python title="binary_search.py" def binary_search_lcro(nums: list[int], target: int) -> int: - """Бинарный поиск (лево замкнутый, право открытый интервал)""" - # Инициализировать лево замкнутый, право открытый интервал [0, n), то есть i и j указывают на первый элемент массива и позицию сразу за последним элементом соответственно + """Двоичный поиск (интервал, замкнутый слева и открытый справа)""" + # Инициализация интервала [0, n), замкнутого слева и открытого справа: i указывает на первый элемент массива, а j — на позицию сразу за последним i, j = 0, len(nums) # Цикл завершается, когда диапазон поиска пуст (при i = j диапазон пуст) while i < j: @@ -399,9 +399,9 @@ comments: true === "C++" ```cpp title="binary_search.cpp" - /* Бинарный поиск (лево замкнутый, право открытый интервал) */ + /* Двоичный поиск (интервал, замкнутый слева и открытый справа) */ int binarySearchLCRO(vector &nums, int target) { - // Инициализировать лево замкнутый, право открытый интервал [0, n), то есть i и j указывают на первый элемент массива и позицию сразу за последним элементом соответственно + // Инициализация интервала [0, n), замкнутого слева и открытого справа: i указывает на первый элемент массива, а j — на позицию сразу за последним int i = 0, j = nums.size(); // Цикл завершается, когда диапазон поиска пуст (при i = j диапазон пуст) while (i < j) { @@ -421,9 +421,9 @@ comments: true === "Java" ```java title="binary_search.java" - /* Бинарный поиск (лево замкнутый, право открытый интервал) */ + /* Двоичный поиск (интервал, замкнутый слева и открытый справа) */ int binarySearchLCRO(int[] nums, int target) { - // Инициализировать лево замкнутый, право открытый интервал [0, n), то есть i и j указывают на первый элемент массива и позицию сразу за последним элементом соответственно + // Инициализация интервала [0, n), замкнутого слева и открытого справа: i указывает на первый элемент массива, а j — на позицию сразу за последним int i = 0, j = nums.length; // Цикл завершается, когда диапазон поиска пуст (при i = j диапазон пуст) while (i < j) { @@ -443,9 +443,9 @@ comments: true === "C#" ```csharp title="binary_search.cs" - /* Бинарный поиск (лево замкнутый, право открытый интервал) */ + /* Двоичный поиск (интервал, замкнутый слева и открытый справа) */ int BinarySearchLCRO(int[] nums, int target) { - // Инициализировать лево замкнутый, право открытый интервал [0, n), то есть i и j указывают на первый элемент массива и позицию сразу за последним элементом соответственно + // Инициализация интервала [0, n), замкнутого слева и открытого справа: i указывает на первый элемент массива, а j — на позицию сразу за последним int i = 0, j = nums.Length; // Цикл завершается, когда диапазон поиска пуст (при i = j диапазон пуст) while (i < j) { @@ -465,9 +465,9 @@ comments: true === "Go" ```go title="binary_search.go" - /* Бинарный поиск (лево замкнутый, право открытый интервал) */ + /* Двоичный поиск (интервал, замкнутый слева и открытый справа) */ func binarySearchLCRO(nums []int, target int) int { - // Инициализировать лево замкнутый, право открытый интервал [0, n), то есть i и j указывают на первый элемент массива и позицию сразу за последним элементом соответственно + // Инициализация интервала [0, n), замкнутого слева и открытого справа: i указывает на первый элемент массива, а j — на позицию сразу за последним i, j := 0, len(nums) // Цикл завершается, когда диапазон поиска пуст (при i = j диапазон пуст) for i < j { @@ -488,9 +488,9 @@ comments: true === "Swift" ```swift title="binary_search.swift" - /* Бинарный поиск (лево замкнутый, право открытый интервал) */ + /* Двоичный поиск (интервал, замкнутый слева и открытый справа) */ func binarySearchLCRO(nums: [Int], target: Int) -> Int { - // Инициализировать лево замкнутый, право открытый интервал [0, n), то есть i и j указывают на первый элемент массива и позицию сразу за последним элементом соответственно + // Инициализация интервала [0, n), замкнутого слева и открытого справа: i указывает на первый элемент массива, а j — на позицию сразу за последним var i = nums.startIndex var j = nums.endIndex // Цикл завершается, когда диапазон поиска пуст (при i = j диапазон пуст) @@ -512,9 +512,9 @@ comments: true === "JS" ```javascript title="binary_search.js" - /* Бинарный поиск (лево замкнутый, право открытый интервал) */ + /* Двоичный поиск (интервал, замкнутый слева и открытый справа) */ function binarySearchLCRO(nums, target) { - // Инициализировать лево замкнутый, право открытый интервал [0, n), то есть i и j указывают на первый элемент массива и позицию сразу за последним элементом соответственно + // Инициализация интервала [0, n), замкнутого слева и открытого справа: i указывает на первый элемент массива, а j — на позицию сразу за последним let i = 0, j = nums.length; // Цикл завершается, когда диапазон поиска пуст (при i = j диапазон пуст) @@ -538,9 +538,9 @@ comments: true === "TS" ```typescript title="binary_search.ts" - /* Бинарный поиск (лево замкнутый, право открытый интервал) */ + /* Двоичный поиск (интервал, замкнутый слева и открытый справа) */ function binarySearchLCRO(nums: number[], target: number): number { - // Инициализировать лево замкнутый, право открытый интервал [0, n), то есть i и j указывают на первый элемент массива и позицию сразу за последним элементом соответственно + // Инициализация интервала [0, n), замкнутого слева и открытого справа: i указывает на первый элемент массива, а j — на позицию сразу за последним let i = 0, j = nums.length; // Цикл завершается, когда диапазон поиска пуст (при i = j диапазон пуст) @@ -565,9 +565,9 @@ comments: true === "Dart" ```dart title="binary_search.dart" - /* Бинарный поиск (лево замкнутый, право открытый интервал) */ + /* Двоичный поиск (интервал, замкнутый слева и открытый справа) */ int binarySearchLCRO(List nums, int target) { - // Инициализировать лево замкнутый, право открытый интервал [0, n), то есть i и j указывают на первый элемент массива и позицию сразу за последним элементом соответственно + // Инициализация интервала [0, n), замкнутого слева и открытого справа: i указывает на первый элемент массива, а j — на позицию сразу за последним int i = 0, j = nums.length; // Цикл завершается, когда диапазон поиска пуст (при i = j диапазон пуст) while (i < j) { @@ -591,9 +591,9 @@ comments: true === "Rust" ```rust title="binary_search.rs" - /* Бинарный поиск (лево замкнутый, право открытый интервал) */ + /* Двоичный поиск (интервал, замкнутый слева и открытый справа) */ fn binary_search_lcro(nums: &[i32], target: i32) -> i32 { - // Инициализировать лево замкнутый, право открытый интервал [0, n), то есть i и j указывают на первый элемент массива и позицию сразу за последним элементом соответственно + // Инициализация интервала [0, n), замкнутого слева и открытого справа: i указывает на первый элемент массива, а j — на позицию сразу за последним let mut i = 0; let mut j = nums.len() as i32; // Цикл завершается, когда диапазон поиска пуст (при i = j диапазон пуст) @@ -618,9 +618,9 @@ comments: true === "C" ```c title="binary_search.c" - /* Бинарный поиск (лево замкнутый, право открытый интервал) */ + /* Двоичный поиск (интервал, замкнутый слева и открытый справа) */ int binarySearchLCRO(int *nums, int len, int target) { - // Инициализировать лево замкнутый, право открытый интервал [0, n), то есть i и j указывают на первый элемент массива и позицию сразу за последним элементом соответственно + // Инициализация интервала [0, n), замкнутого слева и открытого справа: i указывает на первый элемент массива, а j — на позицию сразу за последним int i = 0, j = len; // Цикл завершается, когда диапазон поиска пуст (при i = j диапазон пуст) while (i < j) { @@ -640,9 +640,9 @@ comments: true === "Kotlin" ```kotlin title="binary_search.kt" - /* Бинарный поиск (лево замкнутый, право открытый интервал) */ + /* Двоичный поиск (интервал, замкнутый слева и открытый справа) */ fun binarySearchLCRO(nums: IntArray, target: Int): Int { - // Инициализировать лево замкнутый, право открытый интервал [0, n), то есть i и j указывают на первый элемент массива и позицию сразу за последним элементом соответственно + // Инициализация интервала [0, n), замкнутого слева и открытого справа: i указывает на первый элемент массива, а j — на позицию сразу за последним var i = 0 var j = nums.size // Цикл завершается, когда диапазон поиска пуст (при i = j диапазон пуст) @@ -663,9 +663,9 @@ comments: true === "Ruby" ```ruby title="binary_search.rb" - ### Бинарный поиск (лево замкнутый, право открытый интервал) ### + ### Двоичный поиск (интервал, замкнутый слева и открытый справа) ### def binary_search_lcro(nums, target) - # Инициализировать лево замкнутый, право открытый интервал [0, n), то есть i и j указывают на первый элемент массива и позицию сразу за последним элементом соответственно + # Инициализация интервала [0, n), замкнутого слева и открытого справа: i указывает на первый элемент массива, а j — на позицию сразу за последним i, j = 0, nums.length # Цикл завершается, когда диапазон поиска пуст (при i = j диапазон пуст) @@ -688,12 +688,12 @@ comments: true ??? pythontutor "Визуализация кода" -
- +
+ Как показано на рисунке 10-3, в этих двух вариантах представления интервала различаются инициализация, условие цикла и операция сужения интервала в алгоритме двоичного поиска. -Поскольку в записи «двойной замкнутый интервал» обе границы являются закрытыми, операции сужения интервала при помощи указателей $i$ и $j$ тоже получаются симметричными. Из-за этого в таком варианте сложнее допустить ошибку, **поэтому обычно рекомендуется использовать именно запись «двойной замкнутый интервал»**. +Поскольку в записи «замкнутый интервал» обе границы являются закрытыми, операции сужения интервала при помощи указателей $i$ и $j$ тоже получаются симметричными. Из-за этого в таком варианте сложнее допустить ошибку, **поэтому обычно рекомендуется использовать именно запись «замкнутый интервал»**. ![Два определения интервалов](binary_search.assets/binary_search_ranges.png){ class="animation-figure" } diff --git a/ru/docs/chapter_searching/binary_search_edge.md b/ru/docs/chapter_searching/binary_search_edge.md index f4b966553..20c1eb495 100644 --- a/ru/docs/chapter_searching/binary_search_edge.md +++ b/ru/docs/chapter_searching/binary_search_edge.md @@ -23,20 +23,20 @@ comments: true ```python title="binary_search_edge.py" def binary_search_left_edge(nums: list[int], target: int) -> int: - """Бинарный поиск самого левого target""" + """Двоичный поиск самого левого элемента target""" # Эквивалентно поиску точки вставки target i = binary_search_insertion(nums, target) # target не найден, вернуть -1 if i == len(nums) or nums[i] != target: return -1 - # Найти target и вернуть индекс i + # target найден, возвращается индекс i return i ``` === "C++" ```cpp title="binary_search_edge.cpp" - /* Бинарный поиск самого левого target */ + /* Двоичный поиск самого левого элемента target */ int binarySearchLeftEdge(vector &nums, int target) { // Эквивалентно поиску точки вставки target int i = binarySearchInsertion(nums, target); @@ -44,7 +44,7 @@ comments: true if (i == nums.size() || nums[i] != target) { return -1; } - // Найти target и вернуть индекс i + // target найден, возвращается индекс i return i; } ``` @@ -52,7 +52,7 @@ comments: true === "Java" ```java title="binary_search_edge.java" - /* Бинарный поиск самого левого target */ + /* Двоичный поиск самого левого элемента target */ int binarySearchLeftEdge(int[] nums, int target) { // Эквивалентно поиску точки вставки target int i = binary_search_insertion.binarySearchInsertion(nums, target); @@ -60,7 +60,7 @@ comments: true if (i == nums.length || nums[i] != target) { return -1; } - // Найти target и вернуть индекс i + // target найден, возвращается индекс i return i; } ``` @@ -68,7 +68,7 @@ comments: true === "C#" ```csharp title="binary_search_edge.cs" - /* Бинарный поиск самого левого target */ + /* Двоичный поиск самого левого элемента target */ int BinarySearchLeftEdge(int[] nums, int target) { // Эквивалентно поиску точки вставки target int i = binary_search_insertion.BinarySearchInsertion(nums, target); @@ -76,7 +76,7 @@ comments: true if (i == nums.Length || nums[i] != target) { return -1; } - // Найти target и вернуть индекс i + // target найден, возвращается индекс i return i; } ``` @@ -84,7 +84,7 @@ comments: true === "Go" ```go title="binary_search_edge.go" - /* Бинарный поиск самого левого target */ + /* Двоичный поиск самого левого элемента target */ func binarySearchLeftEdge(nums []int, target int) int { // Эквивалентно поиску точки вставки target i := binarySearchInsertion(nums, target) @@ -92,7 +92,7 @@ comments: true if i == len(nums) || nums[i] != target { return -1 } - // Найти target и вернуть индекс i + // target найден, возвращается индекс i return i } ``` @@ -100,7 +100,7 @@ comments: true === "Swift" ```swift title="binary_search_edge.swift" - /* Бинарный поиск самого левого target */ + /* Двоичный поиск самого левого элемента target */ func binarySearchLeftEdge(nums: [Int], target: Int) -> Int { // Эквивалентно поиску точки вставки target let i = binarySearchInsertion(nums: nums, target: target) @@ -108,7 +108,7 @@ comments: true if i == nums.endIndex || nums[i] != target { return -1 } - // Найти target и вернуть индекс i + // target найден, возвращается индекс i return i } ``` @@ -116,7 +116,7 @@ comments: true === "JS" ```javascript title="binary_search_edge.js" - /* Бинарный поиск самого левого target */ + /* Двоичный поиск самого левого элемента target */ function binarySearchLeftEdge(nums, target) { // Эквивалентно поиску точки вставки target const i = binarySearchInsertion(nums, target); @@ -124,7 +124,7 @@ comments: true if (i === nums.length || nums[i] !== target) { return -1; } - // Найти target и вернуть индекс i + // target найден, возвращается индекс i return i; } ``` @@ -132,7 +132,7 @@ comments: true === "TS" ```typescript title="binary_search_edge.ts" - /* Бинарный поиск самого левого target */ + /* Двоичный поиск самого левого элемента target */ function binarySearchLeftEdge(nums: Array, target: number): number { // Эквивалентно поиску точки вставки target const i = binarySearchInsertion(nums, target); @@ -140,7 +140,7 @@ comments: true if (i === nums.length || nums[i] !== target) { return -1; } - // Найти target и вернуть индекс i + // target найден, возвращается индекс i return i; } ``` @@ -148,7 +148,7 @@ comments: true === "Dart" ```dart title="binary_search_edge.dart" - /* Бинарный поиск самого левого target */ + /* Двоичный поиск самого левого элемента target */ int binarySearchLeftEdge(List nums, int target) { // Эквивалентно поиску точки вставки target int i = binarySearchInsertion(nums, target); @@ -156,7 +156,7 @@ comments: true if (i == nums.length || nums[i] != target) { return -1; } - // Найти target и вернуть индекс i + // target найден, возвращается индекс i return i; } ``` @@ -164,7 +164,7 @@ comments: true === "Rust" ```rust title="binary_search_edge.rs" - /* Бинарный поиск самого левого target */ + /* Двоичный поиск самого левого элемента target */ fn binary_search_left_edge(nums: &[i32], target: i32) -> i32 { // Эквивалентно поиску точки вставки target let i = binary_search_insertion(nums, target); @@ -172,7 +172,7 @@ comments: true if i == nums.len() as i32 || nums[i as usize] != target { return -1; } - // Найти target и вернуть индекс i + // target найден, возвращается индекс i i } ``` @@ -180,7 +180,7 @@ comments: true === "C" ```c title="binary_search_edge.c" - /* Бинарный поиск самого левого target */ + /* Двоичный поиск самого левого элемента target */ int binarySearchLeftEdge(int *nums, int numSize, int target) { // Эквивалентно поиску точки вставки target int i = binarySearchInsertion(nums, numSize, target); @@ -188,7 +188,7 @@ comments: true if (i == numSize || nums[i] != target) { return -1; } - // Найти target и вернуть индекс i + // target найден, возвращается индекс i return i; } ``` @@ -196,7 +196,7 @@ comments: true === "Kotlin" ```kotlin title="binary_search_edge.kt" - /* Бинарный поиск самого левого target */ + /* Двоичный поиск самого левого элемента target */ fun binarySearchLeftEdge(nums: IntArray, target: Int): Int { // Эквивалентно поиску точки вставки target val i = binarySearchInsertion(nums, target) @@ -204,7 +204,7 @@ comments: true if (i == nums.size || nums[i] != target) { return -1 } - // Найти target и вернуть индекс i + // target найден, возвращается индекс i return i } ``` @@ -212,7 +212,7 @@ comments: true === "Ruby" ```ruby title="binary_search_edge.rb" - ### Бинарный поиск самого левого target ### + ### Двоичный поиск самого левого элемента target ### def binary_search_left_edge(nums, target) # Эквивалентно поиску точки вставки target i = binary_search_insertion(nums, target) @@ -220,14 +220,14 @@ comments: true # target не найден, вернуть -1 return -1 if i == nums.length || nums[i] != target - i # Найти target и вернуть индекс i + i # target найден, возвращается индекс i end ``` ??? pythontutor "Визуализация кода" -
- +
+ ## 10.3.2   Поиск правой границы @@ -251,7 +251,7 @@ comments: true ```python title="binary_search_edge.py" def binary_search_right_edge(nums: list[int], target: int) -> int: - """Бинарный поиск самого правого target""" + """Двоичный поиск самого правого элемента target""" # Преобразовать задачу в поиск самого левого target + 1 i = binary_search_insertion(nums, target + 1) # j указывает на самый правый target, а i — на первый элемент больше target @@ -259,14 +259,14 @@ comments: true # target не найден, вернуть -1 if j == -1 or nums[j] != target: return -1 - # Найти target и вернуть индекс j + # target найден, возвращается индекс j return j ``` === "C++" ```cpp title="binary_search_edge.cpp" - /* Бинарный поиск самого правого target */ + /* Двоичный поиск самого правого элемента target */ int binarySearchRightEdge(vector &nums, int target) { // Преобразовать задачу в поиск самого левого target + 1 int i = binarySearchInsertion(nums, target + 1); @@ -276,7 +276,7 @@ comments: true if (j == -1 || nums[j] != target) { return -1; } - // Найти target и вернуть индекс j + // target найден, возвращается индекс j return j; } ``` @@ -284,7 +284,7 @@ comments: true === "Java" ```java title="binary_search_edge.java" - /* Бинарный поиск самого правого target */ + /* Двоичный поиск самого правого элемента target */ int binarySearchRightEdge(int[] nums, int target) { // Преобразовать задачу в поиск самого левого target + 1 int i = binary_search_insertion.binarySearchInsertion(nums, target + 1); @@ -294,7 +294,7 @@ comments: true if (j == -1 || nums[j] != target) { return -1; } - // Найти target и вернуть индекс j + // target найден, возвращается индекс j return j; } ``` @@ -302,7 +302,7 @@ comments: true === "C#" ```csharp title="binary_search_edge.cs" - /* Бинарный поиск самого правого target */ + /* Двоичный поиск самого правого элемента target */ int BinarySearchRightEdge(int[] nums, int target) { // Преобразовать задачу в поиск самого левого target + 1 int i = binary_search_insertion.BinarySearchInsertion(nums, target + 1); @@ -312,7 +312,7 @@ comments: true if (j == -1 || nums[j] != target) { return -1; } - // Найти target и вернуть индекс j + // target найден, возвращается индекс j return j; } ``` @@ -320,7 +320,7 @@ comments: true === "Go" ```go title="binary_search_edge.go" - /* Бинарный поиск самого правого target */ + /* Двоичный поиск самого правого элемента target */ func binarySearchRightEdge(nums []int, target int) int { // Преобразовать задачу в поиск самого левого target + 1 i := binarySearchInsertion(nums, target+1) @@ -330,7 +330,7 @@ comments: true if j == -1 || nums[j] != target { return -1 } - // Найти target и вернуть индекс j + // target найден, возвращается индекс j return j } ``` @@ -338,7 +338,7 @@ comments: true === "Swift" ```swift title="binary_search_edge.swift" - /* Бинарный поиск самого правого target */ + /* Двоичный поиск самого правого элемента target */ func binarySearchRightEdge(nums: [Int], target: Int) -> Int { // Преобразовать задачу в поиск самого левого target + 1 let i = binarySearchInsertion(nums: nums, target: target + 1) @@ -348,7 +348,7 @@ comments: true if j == -1 || nums[j] != target { return -1 } - // Найти target и вернуть индекс j + // target найден, возвращается индекс j return j } ``` @@ -356,7 +356,7 @@ comments: true === "JS" ```javascript title="binary_search_edge.js" - /* Бинарный поиск самого правого target */ + /* Двоичный поиск самого правого элемента target */ function binarySearchRightEdge(nums, target) { // Преобразовать задачу в поиск самого левого target + 1 const i = binarySearchInsertion(nums, target + 1); @@ -366,7 +366,7 @@ comments: true if (j === -1 || nums[j] !== target) { return -1; } - // Найти target и вернуть индекс j + // target найден, возвращается индекс j return j; } ``` @@ -374,7 +374,7 @@ comments: true === "TS" ```typescript title="binary_search_edge.ts" - /* Бинарный поиск самого правого target */ + /* Двоичный поиск самого правого элемента target */ function binarySearchRightEdge(nums: Array, target: number): number { // Преобразовать задачу в поиск самого левого target + 1 const i = binarySearchInsertion(nums, target + 1); @@ -384,7 +384,7 @@ comments: true if (j === -1 || nums[j] !== target) { return -1; } - // Найти target и вернуть индекс j + // target найден, возвращается индекс j return j; } ``` @@ -392,7 +392,7 @@ comments: true === "Dart" ```dart title="binary_search_edge.dart" - /* Бинарный поиск самого правого target */ + /* Двоичный поиск самого правого элемента target */ int binarySearchRightEdge(List nums, int target) { // Преобразовать задачу в поиск самого левого target + 1 int i = binarySearchInsertion(nums, target + 1); @@ -402,7 +402,7 @@ comments: true if (j == -1 || nums[j] != target) { return -1; } - // Найти target и вернуть индекс j + // target найден, возвращается индекс j return j; } ``` @@ -410,7 +410,7 @@ comments: true === "Rust" ```rust title="binary_search_edge.rs" - /* Бинарный поиск самого правого target */ + /* Двоичный поиск самого правого элемента target */ fn binary_search_right_edge(nums: &[i32], target: i32) -> i32 { // Преобразовать задачу в поиск самого левого target + 1 let i = binary_search_insertion(nums, target + 1); @@ -420,7 +420,7 @@ comments: true if j == -1 || nums[j as usize] != target { return -1; } - // Найти target и вернуть индекс j + // target найден, возвращается индекс j j } ``` @@ -428,7 +428,7 @@ comments: true === "C" ```c title="binary_search_edge.c" - /* Бинарный поиск самого правого target */ + /* Двоичный поиск самого правого элемента target */ int binarySearchRightEdge(int *nums, int numSize, int target) { // Преобразовать задачу в поиск самого левого target + 1 int i = binarySearchInsertion(nums, numSize, target + 1); @@ -438,7 +438,7 @@ comments: true if (j == -1 || nums[j] != target) { return -1; } - // Найти target и вернуть индекс j + // target найден, возвращается индекс j return j; } ``` @@ -446,7 +446,7 @@ comments: true === "Kotlin" ```kotlin title="binary_search_edge.kt" - /* Бинарный поиск самого правого target */ + /* Двоичный поиск самого правого элемента target */ fun binarySearchRightEdge(nums: IntArray, target: Int): Int { // Преобразовать задачу в поиск самого левого target + 1 val i = binarySearchInsertion(nums, target + 1) @@ -456,7 +456,7 @@ comments: true if (j == -1 || nums[j] != target) { return -1 } - // Найти target и вернуть индекс j + // target найден, возвращается индекс j return j } ``` @@ -464,7 +464,7 @@ comments: true === "Ruby" ```ruby title="binary_search_edge.rb" - ### Бинарный поиск самого правого target ### + ### Двоичный поиск самого правого элемента target ### def binary_search_right_edge(nums, target) # Преобразовать задачу в поиск самого левого target + 1 i = binary_search_insertion(nums, target + 1) @@ -475,14 +475,14 @@ comments: true # target не найден, вернуть -1 return -1 if j == -1 || nums[j] != target - j # Найти target и вернуть индекс j + j # target найден, возвращается индекс j end ``` ??? pythontutor "Визуализация кода" -
- +
+ ### 2.   Преобразование в поиск элемента diff --git a/ru/docs/chapter_searching/binary_search_insertion.md b/ru/docs/chapter_searching/binary_search_insertion.md index 8c2d31095..550a339f6 100644 --- a/ru/docs/chapter_searching/binary_search_insertion.md +++ b/ru/docs/chapter_searching/binary_search_insertion.md @@ -32,8 +32,8 @@ comments: true ```python title="binary_search_insertion.py" def binary_search_insertion_simple(nums: list[int], target: int) -> int: - """Бинарный поиск точки вставки (без повторяющихся элементов)""" - i, j = 0, len(nums) - 1 # Инициализировать двусторонне замкнутый интервал [0, n-1] + """Двоичный поиск точки вставки (без повторяющихся элементов)""" + i, j = 0, len(nums) - 1 # Инициализировать замкнутый интервал [0, n-1] while i <= j: m = (i + j) // 2 # Вычислить индекс середины m if nums[m] < target: @@ -41,7 +41,7 @@ comments: true elif nums[m] > target: j = m - 1 # target находится в интервале [i, m-1] else: - return m # Найти target и вернуть точку вставки m + return m # target найден, возвращается точка вставки m # target не найден, вернуть точку вставки i return i ``` @@ -49,9 +49,9 @@ comments: true === "C++" ```cpp title="binary_search_insertion.cpp" - /* Бинарный поиск точки вставки (без повторяющихся элементов) */ + /* Двоичный поиск точки вставки (без повторяющихся элементов) */ int binarySearchInsertionSimple(vector &nums, int target) { - int i = 0, j = nums.size() - 1; // Инициализировать двусторонне замкнутый интервал [0, n-1] + int i = 0, j = nums.size() - 1; // Инициализировать замкнутый интервал [0, n-1] while (i <= j) { int m = i + (j - i) / 2; // Вычислить индекс середины m if (nums[m] < target) { @@ -59,7 +59,7 @@ comments: true } else if (nums[m] > target) { j = m - 1; // target находится в интервале [i, m-1] } else { - return m; // Найти target и вернуть точку вставки m + return m; // target найден, возвращается точка вставки m } } // target не найден, вернуть точку вставки i @@ -70,9 +70,9 @@ comments: true === "Java" ```java title="binary_search_insertion.java" - /* Бинарный поиск точки вставки (без повторяющихся элементов) */ + /* Двоичный поиск точки вставки (без повторяющихся элементов) */ int binarySearchInsertionSimple(int[] nums, int target) { - int i = 0, j = nums.length - 1; // Инициализировать двусторонне замкнутый интервал [0, n-1] + int i = 0, j = nums.length - 1; // Инициализировать замкнутый интервал [0, n-1] while (i <= j) { int m = i + (j - i) / 2; // Вычислить индекс середины m if (nums[m] < target) { @@ -80,7 +80,7 @@ comments: true } else if (nums[m] > target) { j = m - 1; // target находится в интервале [i, m-1] } else { - return m; // Найти target и вернуть точку вставки m + return m; // target найден, возвращается точка вставки m } } // target не найден, вернуть точку вставки i @@ -91,9 +91,9 @@ comments: true === "C#" ```csharp title="binary_search_insertion.cs" - /* Бинарный поиск точки вставки (без повторяющихся элементов) */ + /* Двоичный поиск точки вставки (без повторяющихся элементов) */ int BinarySearchInsertionSimple(int[] nums, int target) { - int i = 0, j = nums.Length - 1; // Инициализировать двусторонне замкнутый интервал [0, n-1] + int i = 0, j = nums.Length - 1; // Инициализировать замкнутый интервал [0, n-1] while (i <= j) { int m = i + (j - i) / 2; // Вычислить индекс середины m if (nums[m] < target) { @@ -101,7 +101,7 @@ comments: true } else if (nums[m] > target) { j = m - 1; // target находится в интервале [i, m-1] } else { - return m; // Найти target и вернуть точку вставки m + return m; // target найден, возвращается точка вставки m } } // target не найден, вернуть точку вставки i @@ -112,9 +112,9 @@ comments: true === "Go" ```go title="binary_search_insertion.go" - /* Бинарный поиск точки вставки (без повторяющихся элементов) */ + /* Двоичный поиск точки вставки (без повторяющихся элементов) */ func binarySearchInsertionSimple(nums []int, target int) int { - // Инициализировать двусторонне замкнутый интервал [0, n-1] + // Инициализировать замкнутый интервал [0, n-1] i, j := 0, len(nums)-1 for i <= j { // Вычислить индекс середины m @@ -126,7 +126,7 @@ comments: true // target находится в интервале [i, m-1] j = m - 1 } else { - // Найти target и вернуть точку вставки m + // target найден, возвращается точка вставки m return m } } @@ -138,9 +138,9 @@ comments: true === "Swift" ```swift title="binary_search_insertion.swift" - /* Бинарный поиск точки вставки (без повторяющихся элементов) */ + /* Двоичный поиск точки вставки (без повторяющихся элементов) */ func binarySearchInsertionSimple(nums: [Int], target: Int) -> Int { - // Инициализировать двусторонне замкнутый интервал [0, n-1] + // Инициализировать замкнутый интервал [0, n-1] var i = nums.startIndex var j = nums.endIndex - 1 while i <= j { @@ -150,7 +150,7 @@ comments: true } else if nums[m] > target { j = m - 1 // target находится в интервале [i, m-1] } else { - return m // Найти target и вернуть точку вставки m + return m // target найден, возвращается точка вставки m } } // target не найден, вернуть точку вставки i @@ -161,10 +161,10 @@ comments: true === "JS" ```javascript title="binary_search_insertion.js" - /* Бинарный поиск точки вставки (без повторяющихся элементов) */ + /* Двоичный поиск точки вставки (без повторяющихся элементов) */ function binarySearchInsertionSimple(nums, target) { let i = 0, - j = nums.length - 1; // Инициализировать двусторонне замкнутый интервал [0, n-1] + j = nums.length - 1; // Инициализировать замкнутый интервал [0, n-1] while (i <= j) { const m = Math.floor(i + (j - i) / 2); // Вычислить индекс середины m, используя Math.floor() для округления вниз if (nums[m] < target) { @@ -172,7 +172,7 @@ comments: true } else if (nums[m] > target) { j = m - 1; // target находится в интервале [i, m-1] } else { - return m; // Найти target и вернуть точку вставки m + return m; // target найден, возвращается точка вставки m } } // target не найден, вернуть точку вставки i @@ -183,13 +183,13 @@ comments: true === "TS" ```typescript title="binary_search_insertion.ts" - /* Бинарный поиск точки вставки (без повторяющихся элементов) */ + /* Двоичный поиск точки вставки (без повторяющихся элементов) */ function binarySearchInsertionSimple( nums: Array, target: number ): number { let i = 0, - j = nums.length - 1; // Инициализировать двусторонне замкнутый интервал [0, n-1] + j = nums.length - 1; // Инициализировать замкнутый интервал [0, n-1] while (i <= j) { const m = Math.floor(i + (j - i) / 2); // Вычислить индекс середины m, используя Math.floor() для округления вниз if (nums[m] < target) { @@ -197,7 +197,7 @@ comments: true } else if (nums[m] > target) { j = m - 1; // target находится в интервале [i, m-1] } else { - return m; // Найти target и вернуть точку вставки m + return m; // target найден, возвращается точка вставки m } } // target не найден, вернуть точку вставки i @@ -208,9 +208,9 @@ comments: true === "Dart" ```dart title="binary_search_insertion.dart" - /* Бинарный поиск точки вставки (без повторяющихся элементов) */ + /* Двоичный поиск точки вставки (без повторяющихся элементов) */ int binarySearchInsertionSimple(List nums, int target) { - int i = 0, j = nums.length - 1; // Инициализировать двусторонне замкнутый интервал [0, n-1] + int i = 0, j = nums.length - 1; // Инициализировать замкнутый интервал [0, n-1] while (i <= j) { int m = i + (j - i) ~/ 2; // Вычислить индекс середины m if (nums[m] < target) { @@ -218,7 +218,7 @@ comments: true } else if (nums[m] > target) { j = m - 1; // target находится в интервале [i, m-1] } else { - return m; // Найти target и вернуть точку вставки m + return m; // target найден, возвращается точка вставки m } } // target не найден, вернуть точку вставки i @@ -229,9 +229,9 @@ comments: true === "Rust" ```rust title="binary_search_insertion.rs" - /* Бинарный поиск точки вставки (без повторяющихся элементов) */ + /* Двоичный поиск точки вставки (без повторяющихся элементов) */ fn binary_search_insertion_simple(nums: &[i32], target: i32) -> i32 { - let (mut i, mut j) = (0, nums.len() as i32 - 1); // Инициализировать двусторонне замкнутый интервал [0, n-1] + let (mut i, mut j) = (0, nums.len() as i32 - 1); // Инициализировать замкнутый интервал [0, n-1] while i <= j { let m = i + (j - i) / 2; // Вычислить индекс середины m if nums[m as usize] < target { @@ -250,9 +250,9 @@ comments: true === "C" ```c title="binary_search_insertion.c" - /* Бинарный поиск точки вставки (без повторяющихся элементов) */ + /* Двоичный поиск точки вставки (без повторяющихся элементов) */ int binarySearchInsertionSimple(int *nums, int numSize, int target) { - int i = 0, j = numSize - 1; // Инициализировать двусторонне замкнутый интервал [0, n-1] + int i = 0, j = numSize - 1; // Инициализировать замкнутый интервал [0, n-1] while (i <= j) { int m = i + (j - i) / 2; // Вычислить индекс середины m if (nums[m] < target) { @@ -260,7 +260,7 @@ comments: true } else if (nums[m] > target) { j = m - 1; // target находится в интервале [i, m-1] } else { - return m; // Найти target и вернуть точку вставки m + return m; // target найден, возвращается точка вставки m } } // target не найден, вернуть точку вставки i @@ -271,10 +271,10 @@ comments: true === "Kotlin" ```kotlin title="binary_search_insertion.kt" - /* Бинарный поиск точки вставки (без повторяющихся элементов) */ + /* Двоичный поиск точки вставки (без повторяющихся элементов) */ fun binarySearchInsertionSimple(nums: IntArray, target: Int): Int { var i = 0 - var j = nums.size - 1 // Инициализировать двусторонне замкнутый интервал [0, n-1] + var j = nums.size - 1 // Инициализировать замкнутый интервал [0, n-1] while (i <= j) { val m = i + (j - i) / 2 // Вычислить индекс середины m if (nums[m] < target) { @@ -282,7 +282,7 @@ comments: true } else if (nums[m] > target) { j = m - 1 // target находится в интервале [i, m-1] } else { - return m // Найти target и вернуть точку вставки m + return m // target найден, возвращается точка вставки m } } // target не найден, вернуть точку вставки i @@ -293,9 +293,9 @@ comments: true === "Ruby" ```ruby title="binary_search_insertion.rb" - ### Бинарный поиск точки вставки (без повторяющихся элементов) ### + ### Двоичный поиск точки вставки (без повторяющихся элементов) ### def binary_search_insertion_simple(nums, target) - # Инициализировать двусторонне замкнутый интервал [0, n-1] + # Инициализировать замкнутый интервал [0, n-1] i, j = 0, nums.length - 1 while i <= j @@ -307,7 +307,7 @@ comments: true elsif nums[m] > target j = m - 1 # target находится в интервале [i, m-1] else - return m # Найти target и вернуть точку вставки m + return m # target найден, возвращается точка вставки m end end @@ -317,8 +317,8 @@ comments: true ??? pythontutor "Визуализация кода" -
- +
+ ## 10.2.2   Случай с повторяющимися элементами @@ -380,8 +380,8 @@ comments: true ```python title="binary_search_insertion.py" def binary_search_insertion(nums: list[int], target: int) -> int: - """Бинарный поиск точки вставки (с повторяющимися элементами)""" - i, j = 0, len(nums) - 1 # Инициализировать двусторонне замкнутый интервал [0, n-1] + """Двоичный поиск точки вставки (с повторяющимися элементами)""" + i, j = 0, len(nums) - 1 # Инициализировать замкнутый интервал [0, n-1] while i <= j: m = (i + j) // 2 # Вычислить индекс середины m if nums[m] < target: @@ -397,9 +397,9 @@ comments: true === "C++" ```cpp title="binary_search_insertion.cpp" - /* Бинарный поиск точки вставки (с повторяющимися элементами) */ + /* Двоичный поиск точки вставки (с повторяющимися элементами) */ int binarySearchInsertion(vector &nums, int target) { - int i = 0, j = nums.size() - 1; // Инициализировать двусторонне замкнутый интервал [0, n-1] + int i = 0, j = nums.size() - 1; // Инициализировать замкнутый интервал [0, n-1] while (i <= j) { int m = i + (j - i) / 2; // Вычислить индекс середины m if (nums[m] < target) { @@ -418,9 +418,9 @@ comments: true === "Java" ```java title="binary_search_insertion.java" - /* Бинарный поиск точки вставки (с повторяющимися элементами) */ + /* Двоичный поиск точки вставки (с повторяющимися элементами) */ int binarySearchInsertion(int[] nums, int target) { - int i = 0, j = nums.length - 1; // Инициализировать двусторонне замкнутый интервал [0, n-1] + int i = 0, j = nums.length - 1; // Инициализировать замкнутый интервал [0, n-1] while (i <= j) { int m = i + (j - i) / 2; // Вычислить индекс середины m if (nums[m] < target) { @@ -439,9 +439,9 @@ comments: true === "C#" ```csharp title="binary_search_insertion.cs" - /* Бинарный поиск точки вставки (с повторяющимися элементами) */ + /* Двоичный поиск точки вставки (с повторяющимися элементами) */ int BinarySearchInsertion(int[] nums, int target) { - int i = 0, j = nums.Length - 1; // Инициализировать двусторонне замкнутый интервал [0, n-1] + int i = 0, j = nums.Length - 1; // Инициализировать замкнутый интервал [0, n-1] while (i <= j) { int m = i + (j - i) / 2; // Вычислить индекс середины m if (nums[m] < target) { @@ -460,9 +460,9 @@ comments: true === "Go" ```go title="binary_search_insertion.go" - /* Бинарный поиск точки вставки (с повторяющимися элементами) */ + /* Двоичный поиск точки вставки (с повторяющимися элементами) */ func binarySearchInsertion(nums []int, target int) int { - // Инициализировать двусторонне замкнутый интервал [0, n-1] + // Инициализировать замкнутый интервал [0, n-1] i, j := 0, len(nums)-1 for i <= j { // Вычислить индекс середины m @@ -486,9 +486,9 @@ comments: true === "Swift" ```swift title="binary_search_insertion.swift" - /* Бинарный поиск точки вставки (с повторяющимися элементами) */ + /* Двоичный поиск точки вставки (с повторяющимися элементами) */ func binarySearchInsertion(nums: [Int], target: Int) -> Int { - // Инициализировать двусторонне замкнутый интервал [0, n-1] + // Инициализировать замкнутый интервал [0, n-1] var i = nums.startIndex var j = nums.endIndex - 1 while i <= j { @@ -509,10 +509,10 @@ comments: true === "JS" ```javascript title="binary_search_insertion.js" - /* Бинарный поиск точки вставки (с повторяющимися элементами) */ + /* Двоичный поиск точки вставки (с повторяющимися элементами) */ function binarySearchInsertion(nums, target) { let i = 0, - j = nums.length - 1; // Инициализировать двусторонне замкнутый интервал [0, n-1] + j = nums.length - 1; // Инициализировать замкнутый интервал [0, n-1] while (i <= j) { const m = Math.floor(i + (j - i) / 2); // Вычислить индекс середины m, используя Math.floor() для округления вниз if (nums[m] < target) { @@ -531,10 +531,10 @@ comments: true === "TS" ```typescript title="binary_search_insertion.ts" - /* Бинарный поиск точки вставки (с повторяющимися элементами) */ + /* Двоичный поиск точки вставки (с повторяющимися элементами) */ function binarySearchInsertion(nums: Array, target: number): number { let i = 0, - j = nums.length - 1; // Инициализировать двусторонне замкнутый интервал [0, n-1] + j = nums.length - 1; // Инициализировать замкнутый интервал [0, n-1] while (i <= j) { const m = Math.floor(i + (j - i) / 2); // Вычислить индекс середины m, используя Math.floor() для округления вниз if (nums[m] < target) { @@ -553,9 +553,9 @@ comments: true === "Dart" ```dart title="binary_search_insertion.dart" - /* Бинарный поиск точки вставки (с повторяющимися элементами) */ + /* Двоичный поиск точки вставки (с повторяющимися элементами) */ int binarySearchInsertion(List nums, int target) { - int i = 0, j = nums.length - 1; // Инициализировать двусторонне замкнутый интервал [0, n-1] + int i = 0, j = nums.length - 1; // Инициализировать замкнутый интервал [0, n-1] while (i <= j) { int m = i + (j - i) ~/ 2; // Вычислить индекс середины m if (nums[m] < target) { @@ -574,9 +574,9 @@ comments: true === "Rust" ```rust title="binary_search_insertion.rs" - /* Бинарный поиск точки вставки (с повторяющимися элементами) */ + /* Двоичный поиск точки вставки (с повторяющимися элементами) */ pub fn binary_search_insertion(nums: &[i32], target: i32) -> i32 { - let (mut i, mut j) = (0, nums.len() as i32 - 1); // Инициализировать двусторонне замкнутый интервал [0, n-1] + let (mut i, mut j) = (0, nums.len() as i32 - 1); // Инициализировать замкнутый интервал [0, n-1] while i <= j { let m = i + (j - i) / 2; // Вычислить индекс середины m if nums[m as usize] < target { @@ -595,9 +595,9 @@ comments: true === "C" ```c title="binary_search_insertion.c" - /* Бинарный поиск точки вставки (с повторяющимися элементами) */ + /* Двоичный поиск точки вставки (с повторяющимися элементами) */ int binarySearchInsertion(int *nums, int numSize, int target) { - int i = 0, j = numSize - 1; // Инициализировать двусторонне замкнутый интервал [0, n-1] + int i = 0, j = numSize - 1; // Инициализировать замкнутый интервал [0, n-1] while (i <= j) { int m = i + (j - i) / 2; // Вычислить индекс середины m if (nums[m] < target) { @@ -616,10 +616,10 @@ comments: true === "Kotlin" ```kotlin title="binary_search_insertion.kt" - /* Бинарный поиск точки вставки (с повторяющимися элементами) */ + /* Двоичный поиск точки вставки (с повторяющимися элементами) */ fun binarySearchInsertion(nums: IntArray, target: Int): Int { var i = 0 - var j = nums.size - 1 // Инициализировать двусторонне замкнутый интервал [0, n-1] + var j = nums.size - 1 // Инициализировать замкнутый интервал [0, n-1] while (i <= j) { val m = i + (j - i) / 2 // Вычислить индекс середины m if (nums[m] < target) { @@ -638,9 +638,9 @@ comments: true === "Ruby" ```ruby title="binary_search_insertion.rb" - ### Бинарный поиск точки вставки (с повторяющимися элементами) ### + ### Двоичный поиск точки вставки (с повторяющимися элементами) ### def binary_search_insertion(nums, target) - # Инициализировать двусторонне замкнутый интервал [0, n-1] + # Инициализировать замкнутый интервал [0, n-1] i, j = 0, nums.length - 1 while i <= j @@ -662,12 +662,12 @@ comments: true ??? pythontutor "Визуализация кода" -
- +
+ !!! tip - Код в этом разделе записан в стиле «двойного замкнутого интервала». При желании можно самостоятельно реализовать вариант «слева закрыт, справа открыт». + Код в этом разделе записан в стиле «замкнутого интервала». При желании можно самостоятельно реализовать вариант «слева закрыт, справа открыт». Если смотреть в целом, суть двоичного поиска сводится к тому, что для указателей $i$ и $j$ заранее задаются ориентиры поиска. Целью может быть конкретный элемент, например `target` , а может быть и диапазон элементов, например все элементы, меньшие `target` . diff --git a/ru/docs/chapter_searching/exercises.md b/ru/docs/chapter_searching/exercises.md index 2395c56df..1be010de2 100644 --- a/ru/docs/chapter_searching/exercises.md +++ b/ru/docs/chapter_searching/exercises.md @@ -9,7 +9,7 @@ comments: true ### 1.   Как двоичный поиск сужает область поиска Найдите число 16 в упорядоченном массиве `[2, 5, 8, 12, 16, 23, 38]`. -Используйте двойной замкнутый интервал `[i, j]` и середину +Используйте замкнутый интервал `[i, j]` и середину $m=i+(j-i)/2$ с округлением вниз. Для каждой итерации запишите `(i, j, m)`, средний элемент и способ дальнейшего сужения интервала, @@ -46,7 +46,7 @@ $m=i+(j-i)/2$ с округлением вниз. Левая граница в этом массиве имеет индекс 1, а правая — индекс 3. 2. При поиске левой границы, даже если средний элемент равен 2, нужно продолжить поиск слева, - например, при двойном замкнутом интервале присвоить `j = m - 1`. + например, при замкнутом интервале присвоить `j = m - 1`. 3. При поиске правой границы после совпадения среднего элемента с 2 нужно продолжить поиск справа, например, присвоить `i = m + 1`. @@ -93,7 +93,7 @@ $m=i+(j-i)/2$ с округлением вниз. ??? tip "Подсказки" 1. Ответ может быть равен 0 или длине массива n - 2. При двойном замкнутом интервале, если `nums[mid]` больше или равно `target`, присвойте `right = mid - 1` и продолжите проверять позиции левее; иначе присвойте `left = mid + 1` + 2. При замкнутом интервале, если `nums[mid]` больше или равно `target`, присвойте `right = mid - 1` и продолжите проверять позиции левее; иначе присвойте `left = mid + 1` 3. После завершения цикла left будет позицией вставки [LeetCode](https://leetcode.com/problems/search-insert-position/){ .rounded-button .exercise-button target="_blank" rel="noopener noreferrer" } diff --git a/ru/docs/chapter_searching/index.md b/ru/docs/chapter_searching/index.md index 10e04625e..dbf221b5e 100644 --- a/ru/docs/chapter_searching/index.md +++ b/ru/docs/chapter_searching/index.md @@ -18,7 +18,7 @@ icon: material/text-search - [10.1   Двоичный поиск](binary_search.md) - [10.2   Двоичный поиск точки вставки](binary_search_insertion.md) - [10.3   Двоичный поиск границ](binary_search_edge.md) -- [10.4   Стратегии оптимизации хеширования](replace_linear_by_hashing.md) +- [10.4   Стратегии оптимизации с помощью хеширования](replace_linear_by_hashing.md) - [10.5   Переосмысление алгоритмов поиска](searching_algorithm_revisited.md) - [10.6   Резюме](summary.md) - [10.7   Упражнения](exercises.md) diff --git a/ru/docs/chapter_searching/replace_linear_by_hashing.md b/ru/docs/chapter_searching/replace_linear_by_hashing.md index 3eb637ade..b2b68aa37 100644 --- a/ru/docs/chapter_searching/replace_linear_by_hashing.md +++ b/ru/docs/chapter_searching/replace_linear_by_hashing.md @@ -2,7 +2,7 @@ comments: true --- -# 10.4   Стратегии оптимизации хеширования +# 10.4   Стратегии оптимизации с помощью хеширования В алгоритмических задачах **мы часто заменяем линейный поиск на хеш-поиск, чтобы уменьшить временную сложность алгоритма**. Разберем одну задачу, чтобы лучше понять этот прием. diff --git a/ru/docs/chapter_searching/searching_algorithm_revisited.md b/ru/docs/chapter_searching/searching_algorithm_revisited.md index 4a5244e59..55c6ad985 100644 --- a/ru/docs/chapter_searching/searching_algorithm_revisited.md +++ b/ru/docs/chapter_searching/searching_algorithm_revisited.md @@ -60,8 +60,8 @@ comments: true | Вставка элемента | $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(n \log n)$ | Построение дерева $O(n \log n)$ | Построение хеш-таблицы $O(n)$ | +| Упорядоченность данных | Неупорядоченные | Упорядоченные | Упорядоченные | Неупорядоченные | diff --git a/ru/docs/chapter_stack_and_queue/deque.md b/ru/docs/chapter_stack_and_queue/deque.md index 6e585e293..2eceba311 100644 --- a/ru/docs/chapter_stack_and_queue/deque.md +++ b/ru/docs/chapter_stack_and_queue/deque.md @@ -216,7 +216,7 @@ comments: true deque.push(2); deque.push(5); deque.push(4); - // Обрати внимание: поскольку это массив, метод unshift() имеет сложность O(n) + // Обратите внимание: поскольку это массив, метод unshift() имеет сложность O(n) deque.unshift(3); deque.unshift(1); @@ -225,7 +225,7 @@ comments: true const peekLast = deque[deque.length - 1]; /* Извлечь элементы из очереди */ - // Обрати внимание: поскольку это массив, метод shift() имеет сложность O(n) + // Обратите внимание: поскольку это массив, метод shift() имеет сложность O(n) const popFront = deque.shift(); const popBack = deque.pop(); @@ -247,7 +247,7 @@ comments: true deque.push(2); deque.push(5); deque.push(4); - // Обрати внимание: поскольку это массив, метод unshift() имеет сложность O(n) + // Обратите внимание: поскольку это массив, метод unshift() имеет сложность O(n) deque.unshift(3); deque.unshift(1); @@ -256,7 +256,7 @@ comments: true const peekLast: number = deque[deque.length - 1]; /* Извлечь элементы из очереди */ - // Обрати внимание: поскольку это массив, метод shift() имеет сложность O(n) + // Обратите внимание: поскольку это массив, метод shift() имеет сложность O(n) const popFront: number = deque.shift() as number; const popBack: number = deque.pop() as number; @@ -373,7 +373,7 @@ comments: true deque << 2 deque << 5 deque << 4 - # Обрати внимание: поскольку это массив, метод Array#unshift имеет сложность O(n) + # Обратите внимание: поскольку это массив, метод Array#unshift имеет сложность O(n) deque.unshift(3) deque.unshift(1) @@ -382,7 +382,7 @@ comments: true peek_last = deque.last # Извлечь элементы из очереди - # Обрати внимание: поскольку это массив, метод Array#shift имеет сложность O(n) + # Обратите внимание: поскольку это массив, метод Array#shift имеет сложность O(n) pop_front = deque.shift pop_back = deque.pop @@ -628,7 +628,7 @@ comments: true // Если в очереди один элемент, начало и конец указывают на один узел if (queSize == 1) { val = front->val; - delete front; // Освобождаем общий узел один раз + delete front; // Оба указателя указывают на один узел, поэтому достаточно освободить его один раз front = nullptr; rear = nullptr; } @@ -1274,7 +1274,7 @@ comments: true if (this.#queSize === 0) { return null; } - const value = this.#front.val; // Сохраняем значение головного узла + const value = this.#front.val; // Сохранение значения головного узла // Если в очереди один элемент, начало и конец указывают на один узел if (this.#queSize === 1) { this.#front = null; @@ -1411,7 +1411,7 @@ comments: true if (this.queSize === 0) { return null; } - const value: number = this.front.val; // Сохраняем значение головного узла + const value: number = this.front.val; // Сохранение значения головного узла // Если в очереди один элемент, начало и конец указывают на один узел if (this.queSize === 1) { this.front = null; @@ -1879,7 +1879,7 @@ comments: true // Если в очереди один элемент, начало и конец указывают на один узел if (deque->queSize == 1) { val = deque->front->val; - delDoublyListNode(deque->front); // Освобождаем общий узел один раз + delDoublyListNode(deque->front); // Оба указателя указывают на один узел, поэтому достаточно освободить его один раз deque->front = NULL; deque->rear = NULL; } @@ -3646,4 +3646,4 @@ comments: true Двусторонняя очередь сочетает в себе логику стека и очереди, **поэтому она может покрыть все сценарии применения обеих структур и при этом предоставляет более высокую степень свободы**. -Мы знаем, что функция «undo» в программном обеспечении обычно реализуется с помощью стека: система помещает каждое изменение в стек с помощью `push` , а затем использует `pop` для отмены. Однако, учитывая ограниченность системных ресурсов, программы обычно ограничивают число шагов отмены, например разрешают хранить только $50$ шагов. Когда длина стека превышает этот предел, программе нужно удалить элемент с дна стека, то есть с головы очереди. **Но стек не может реализовать такую операцию, и в этом случае его приходится заменять двусторонней очередью**. Обрати внимание: основная логика «undo» по-прежнему следует стековому правилу LIFO, просто двусторонняя очередь позволяет более гибко реализовать некоторые дополнительные механизмы. +Мы знаем, что функция «undo» в программном обеспечении обычно реализуется с помощью стека: система помещает каждое изменение в стек с помощью `push` , а затем использует `pop` для отмены. Однако, учитывая ограниченность системных ресурсов, программы обычно ограничивают число шагов отмены, например разрешают хранить только $50$ шагов. Когда длина стека превышает этот предел, программе нужно удалить элемент с дна стека, то есть с головы очереди. **Но стек не может реализовать такую операцию, и в этом случае его приходится заменять двусторонней очередью**. Обратите внимание: основная логика «undo» по-прежнему следует стековому правилу LIFO, просто двусторонняя очередь позволяет более гибко реализовать некоторые дополнительные механизмы. diff --git a/ru/docs/chapter_stack_and_queue/queue.md b/ru/docs/chapter_stack_and_queue/queue.md index 657b20b88..4eed5fbf6 100644 --- a/ru/docs/chapter_stack_and_queue/queue.md +++ b/ru/docs/chapter_stack_and_queue/queue.md @@ -356,7 +356,7 @@ comments: true peek = queue.first # Извлечь элемент из очереди - # Обрати внимание: поскольку это массив, метод Array#shift имеет сложность O(n) + # Обратите внимание: поскольку это массив, метод Array#shift имеет сложность O(n) pop = queue.shift # Получить длину очереди