mirror of
https://github.com/krahets/hello-algo.git
synced 2026-07-16 16:56:06 +00:00
deploy
This commit is contained in:
@@ -65,8 +65,8 @@
|
||||
|
||||
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Noto+Sans:300,300i,400,400i,500,500i,700,700i%7CJetBrains+Mono:400,400i,700,700i&display=fallback">
|
||||
<style>:root{--md-text-font:"Noto Sans";--md-code-font:"JetBrains Mono"}</style>
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=PT+Sans:300,300i,400,400i,500,500i,700,700i%7CJetBrains+Mono:400,400i,700,700i&display=fallback">
|
||||
<style>:root{--md-text-font:"PT Sans";--md-code-font:"JetBrains Mono"}</style>
|
||||
|
||||
|
||||
|
||||
@@ -574,7 +574,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
Глава 1. Знакомство с алгоритмами
|
||||
Глава 1. Введение в алгоритмы
|
||||
|
||||
|
||||
|
||||
@@ -596,7 +596,7 @@
|
||||
<span class="md-nav__icon md-icon"></span>
|
||||
|
||||
|
||||
Глава 1. Знакомство с алгоритмами
|
||||
Глава 1. Введение в алгоритмы
|
||||
|
||||
|
||||
</label>
|
||||
@@ -646,7 +646,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
1.2 Что такое структуры данных и алгоритмы
|
||||
1.2 Что такое алгоритм
|
||||
|
||||
|
||||
|
||||
@@ -1183,7 +1183,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
Глава 4. Массив и связный список
|
||||
Глава 4. Массивы и списки
|
||||
|
||||
|
||||
|
||||
@@ -1205,7 +1205,7 @@
|
||||
<span class="md-nav__icon md-icon"></span>
|
||||
|
||||
|
||||
Глава 4. Массив и связный список
|
||||
Глава 4. Массивы и списки
|
||||
|
||||
|
||||
</label>
|
||||
@@ -1475,7 +1475,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
4.4 Память и кеш *
|
||||
4.4 Оперативная память и кэш *
|
||||
|
||||
|
||||
|
||||
@@ -1757,7 +1757,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
Глава 6. Хеширование
|
||||
Глава 6. Хеш-таблицы
|
||||
|
||||
|
||||
|
||||
@@ -1779,7 +1779,7 @@
|
||||
<span class="md-nav__icon md-icon"></span>
|
||||
|
||||
|
||||
Глава 6. Хеширование
|
||||
Глава 6. Хеш-таблицы
|
||||
|
||||
|
||||
</label>
|
||||
@@ -1857,7 +1857,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
6.3 Хеш-алгоритмы
|
||||
6.3 Алгоритмы хеширования
|
||||
|
||||
|
||||
|
||||
@@ -1952,7 +1952,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
Глава 7. Дерево
|
||||
Глава 7. Деревья
|
||||
|
||||
|
||||
|
||||
@@ -1974,7 +1974,7 @@
|
||||
<span class="md-nav__icon md-icon"></span>
|
||||
|
||||
|
||||
Глава 7. Дерево
|
||||
Глава 7. Деревья
|
||||
|
||||
|
||||
</label>
|
||||
@@ -2052,7 +2052,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
7.3 Представление дерева массивом
|
||||
7.3 Представление двоичного дерева массивом
|
||||
|
||||
|
||||
|
||||
@@ -2136,7 +2136,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
7.6 Резюме
|
||||
7.6 Краткие итоги
|
||||
|
||||
|
||||
|
||||
@@ -2299,7 +2299,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
8.3 Задача Top-K
|
||||
8.3 Задача Top-k
|
||||
|
||||
|
||||
|
||||
@@ -2390,7 +2390,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
Глава 9. Граф
|
||||
Глава 9. Графы
|
||||
|
||||
|
||||
|
||||
@@ -2412,7 +2412,7 @@
|
||||
<span class="md-nav__icon md-icon"></span>
|
||||
|
||||
|
||||
Глава 9. Граф
|
||||
Глава 9. Графы
|
||||
|
||||
|
||||
</label>
|
||||
@@ -2462,7 +2462,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
9.2 Базовые операции над графами
|
||||
9.2 Базовые операции графа
|
||||
|
||||
|
||||
|
||||
@@ -2518,7 +2518,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
9.4 Резюме
|
||||
9.4 Краткие итоги
|
||||
|
||||
|
||||
|
||||
@@ -2657,7 +2657,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.2 Точка вставки двоичного поиска
|
||||
10.2 Двоичный поиск точки вставки
|
||||
|
||||
|
||||
|
||||
@@ -2685,7 +2685,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.3 Граничные случаи двоичного поиска
|
||||
10.3 Двоичный поиск границ
|
||||
|
||||
|
||||
|
||||
@@ -2713,7 +2713,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.4 Стратегия оптимизации через хеширование
|
||||
10.4 Стратегии оптимизации хеширования
|
||||
|
||||
|
||||
|
||||
@@ -2741,7 +2741,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.5 Алгоритмы поиска: новый взгляд
|
||||
10.5 Переосмысление алгоритмов поиска
|
||||
|
||||
|
||||
|
||||
@@ -2946,7 +2946,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
11.3 Пузырьковая сортировка
|
||||
11.3 Сортировка пузырьком
|
||||
|
||||
|
||||
|
||||
@@ -2974,7 +2974,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
11.4 Сортировка вставкой
|
||||
11.4 Сортировка вставками
|
||||
|
||||
|
||||
|
||||
@@ -3279,7 +3279,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
12.1 Алгоритмы разделяй и властвуй
|
||||
12.1 Стратегия разделяй и властвуй
|
||||
|
||||
|
||||
|
||||
@@ -3307,7 +3307,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
12.2 Стратегия поиска разделяй и властвуй
|
||||
12.2 Поисковая стратегия разделяй и властвуй
|
||||
|
||||
|
||||
|
||||
@@ -3584,7 +3584,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
13.4 Задача о $n$ ферзях
|
||||
13.4 Задача о n ферзях
|
||||
|
||||
|
||||
|
||||
@@ -3725,7 +3725,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
14.1 Введение в динамическое программирование
|
||||
14.1 Первое знакомство с динамическим программированием
|
||||
|
||||
|
||||
|
||||
@@ -3837,7 +3837,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
14.5 Задача о неограниченном рюкзаке
|
||||
14.5 Задача о полном рюкзаке
|
||||
|
||||
|
||||
|
||||
@@ -4543,13 +4543,13 @@
|
||||
|
||||
<!-- Page content -->
|
||||
<h1 id="41">4.1 Массив<a class="headerlink" href="#41" title="Permanent link">¶</a></h1>
|
||||
<p><u>Массив (array)</u> - это линейная структура данных, которая хранит элементы одного типа в непрерывной области памяти. Положение элемента в массиве называется его <u>индексом (index)</u>. На рисунке 4-1 показаны основные понятия, связанные с массивом, и способ его хранения.</p>
|
||||
<p><u>Массив (array)</u> - это линейная структура данных, в которой элементы одного типа хранятся в непрерывной области памяти. Положение элемента в массиве называется его <u>индексом (index)</u>. На рисунке 4-1 показаны основные понятия, связанные с массивом, и способ его хранения.</p>
|
||||
<p><img alt="Определение массива и способ хранения" class="animation-figure" src="../array.assets/array_definition.png" /></p>
|
||||
<p align="center"> Рисунок 4-1 Определение массива и способ хранения </p>
|
||||
|
||||
<h2 id="411">4.1.1 Основные операции с массивом<a class="headerlink" href="#411" title="Permanent link">¶</a></h2>
|
||||
<h3 id="1">1. Инициализация массива<a class="headerlink" href="#1" title="Permanent link">¶</a></h3>
|
||||
<p>В зависимости от задачи мы можем выбрать один из двух способов инициализации массива: без начальных значений или с заданными начальными значениями. Если начальные значения не указаны, большинство языков программирования инициализируют элементы массива значением <span class="arithmatex">\(0\)</span> :</p>
|
||||
<p>Существует два способа инициализации массива: без начальных значений и с заданными начальными значениями. Если начальные значения не указаны, большинство языков программирования инициализируют элементы массива нулями:</p>
|
||||
<div class="tabbed-set tabbed-alternate" data-tabs="1:13"><input checked="checked" id="__tabbed_1_1" name="__tabbed_1" type="radio" /><input id="__tabbed_1_2" name="__tabbed_1" type="radio" /><input id="__tabbed_1_3" name="__tabbed_1" type="radio" /><input id="__tabbed_1_4" name="__tabbed_1" type="radio" /><input id="__tabbed_1_5" name="__tabbed_1" type="radio" /><input id="__tabbed_1_6" name="__tabbed_1" type="radio" /><input id="__tabbed_1_7" name="__tabbed_1" type="radio" /><input id="__tabbed_1_8" name="__tabbed_1" type="radio" /><input id="__tabbed_1_9" name="__tabbed_1" type="radio" /><input id="__tabbed_1_10" name="__tabbed_1" type="radio" /><input id="__tabbed_1_11" name="__tabbed_1" type="radio" /><input id="__tabbed_1_12" name="__tabbed_1" type="radio" /><input id="__tabbed_1_13" name="__tabbed_1" type="radio" /><div class="tabbed-labels"><label for="__tabbed_1_1">Python</label><label for="__tabbed_1_2">C++</label><label for="__tabbed_1_3">Java</label><label for="__tabbed_1_4">C#</label><label for="__tabbed_1_5">Go</label><label for="__tabbed_1_6">Swift</label><label for="__tabbed_1_7">JS</label><label for="__tabbed_1_8">TS</label><label for="__tabbed_1_9">Dart</label><label for="__tabbed_1_10">Rust</label><label for="__tabbed_1_11">C</label><label for="__tabbed_1_12">Kotlin</label><label for="__tabbed_1_13">Ruby</label></div>
|
||||
<div class="tabbed-content">
|
||||
<div class="tabbed-block">
|
||||
@@ -4649,11 +4649,11 @@
|
||||
<p>https://pythontutor.com/render.html#code=%23%20%D0%98%D0%BD%D0%B8%D1%86%D0%B8%D0%B0%D0%BB%D0%B8%D0%B7%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D1%82%D1%8C%20%D0%BC%D0%B0%D1%81%D1%81%D0%B8%D0%B2%0Aarr%20%3D%20%5B0%5D%20%2A%205%20%20%23%20%5B%200%2C%200%2C%200%2C%200%2C%200%20%5D%0Anums%20%3D%20%5B1%2C%203%2C%202%2C%205%2C%204%5D&cumulative=false&curInstr=0&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=311&rawInputLstJSON=%5B%5D&textReferences=false</p>
|
||||
</details>
|
||||
<h3 id="2">2. Доступ к элементам<a class="headerlink" href="#2" title="Permanent link">¶</a></h3>
|
||||
<p>Элементы массива хранятся в непрерывной области памяти, а это означает, что вычислить адрес любого элемента очень просто. Зная адрес массива в памяти (то есть адрес первого элемента) и индекс некоторого элемента, мы можем по формуле с рисунка ниже вычислить адрес этого элемента и напрямую обратиться к нему.</p>
|
||||
<p>Элементы массива хранятся в непрерывной области памяти, что упрощает вычисление их адресов. Зная адрес массива в памяти (то есть адрес первого элемента) и индекс некоторого элемента, мы можем по формуле с рисунка ниже вычислить адрес этого элемента и напрямую обратиться к нему.</p>
|
||||
<p><img alt="Вычисление адреса элемента массива" class="animation-figure" src="../array.assets/array_memory_location_calculation.png" /></p>
|
||||
<p align="center"> Рисунок 4-2 Вычисление адреса элемента массива </p>
|
||||
|
||||
<p>Если посмотреть на рисунок 4-2, можно заметить, что индекс первого элемента массива равен <span class="arithmatex">\(0\)</span> , и это кажется не слишком интуитивным, ведь естественнее было бы начинать счет с <span class="arithmatex">\(1\)</span> . Однако с точки зрения формулы адресации <strong>индекс по сути является смещением относительно адреса памяти</strong>. Смещение первого элемента равно <span class="arithmatex">\(0\)</span> , поэтому индекс <span class="arithmatex">\(0\)</span> вполне логичен.</p>
|
||||
<p>Если посмотреть на рисунок 4-2, можно заметить, что индекс первого элемента массива равен <span class="arithmatex">\(0\)</span> , и это кажется не слишком интуитивным, ведь естественнее было бы начинать счет с <span class="arithmatex">\(1\)</span> . Однако с точки зрения формулы адресации <strong>индекс по сути является смещением относительно адреса памяти</strong>. Смещение первого элемента равно <span class="arithmatex">\(0\)</span> , поэтому индекс <span class="arithmatex">\(0\)</span> полностью логичен.</p>
|
||||
<p>Доступ к элементам массива очень эффективен: любой элемент массива можно получить за <span class="arithmatex">\(O(1)\)</span> времени.</p>
|
||||
<div class="tabbed-set tabbed-alternate" data-tabs="2:13"><input checked="checked" id="__tabbed_2_1" name="__tabbed_2" type="radio" /><input id="__tabbed_2_2" name="__tabbed_2" type="radio" /><input id="__tabbed_2_3" name="__tabbed_2" type="radio" /><input id="__tabbed_2_4" name="__tabbed_2" type="radio" /><input id="__tabbed_2_5" name="__tabbed_2" type="radio" /><input id="__tabbed_2_6" name="__tabbed_2" type="radio" /><input id="__tabbed_2_7" name="__tabbed_2" type="radio" /><input id="__tabbed_2_8" name="__tabbed_2" type="radio" /><input id="__tabbed_2_9" name="__tabbed_2" type="radio" /><input id="__tabbed_2_10" name="__tabbed_2" type="radio" /><input id="__tabbed_2_11" name="__tabbed_2" type="radio" /><input id="__tabbed_2_12" name="__tabbed_2" type="radio" /><input id="__tabbed_2_13" name="__tabbed_2" type="radio" /><div class="tabbed-labels"><label for="__tabbed_2_1">Python</label><label for="__tabbed_2_2">C++</label><label for="__tabbed_2_3">Java</label><label for="__tabbed_2_4">C#</label><label for="__tabbed_2_5">Go</label><label for="__tabbed_2_6">Swift</label><label for="__tabbed_2_7">JS</label><label for="__tabbed_2_8">TS</label><label for="__tabbed_2_9">Dart</label><label for="__tabbed_2_10">Rust</label><label for="__tabbed_2_11">C</label><label for="__tabbed_2_12">Kotlin</label><label for="__tabbed_2_13">Ruby</label></div>
|
||||
<div class="tabbed-content">
|
||||
@@ -4808,11 +4808,11 @@
|
||||
<div style="margin-top: 5px;"><a href="https://pythontutor.com/iframe-embed.html#code=import%20random%0A%0Adef%20random_access%28nums%3A%20list%5Bint%5D%29%20-%3E%20int%3A%0A%20%20%20%20%22%22%22%D0%A1%D0%BB%D1%83%D1%87%D0%B0%D0%B9%D0%BD%D1%8B%D0%B9%20%D0%B4%D0%BE%D1%81%D1%82%D1%83%D0%BF%20%D0%BA%20%D1%8D%D0%BB%D0%B5%D0%BC%D0%B5%D0%BD%D1%82%D1%83%22%22%22%0A%20%20%20%20%23%20%D0%A1%D0%BB%D1%83%D1%87%D0%B0%D0%B9%D0%BD%D1%8B%D0%BC%20%D0%BE%D0%B1%D1%80%D0%B0%D0%B7%D0%BE%D0%BC%20%D0%B2%D1%8B%D0%B1%D1%80%D0%B0%D1%82%D1%8C%20%D1%87%D0%B8%D1%81%D0%BB%D0%BE%20%D0%B8%D0%B7%20%D0%B8%D0%BD%D1%82%D0%B5%D1%80%D0%B2%D0%B0%D0%BB%D0%B0%20%5B0%2C%20len%28nums%29-1%5D%0A%20%20%20%20random_index%20%3D%20random.randint%280%2C%20len%28nums%29%20-%201%29%0A%20%20%20%20%23%20%D0%9F%D0%BE%D0%BB%D1%83%D1%87%D0%B8%D1%82%D1%8C%20%D0%B8%20%D0%B2%D0%B5%D1%80%D0%BD%D1%83%D1%82%D1%8C%20%D1%81%D0%BB%D1%83%D1%87%D0%B0%D0%B9%D0%BD%D1%8B%D0%B9%20%D1%8D%D0%BB%D0%B5%D0%BC%D0%B5%D0%BD%D1%82%0A%20%20%20%20random_num%20%3D%20nums%5Brandom_index%5D%0A%20%20%20%20return%20random_num%0A%0A%22%22%22Driver%20Code%22%22%22%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20%23%20%D0%98%D0%BD%D0%B8%D1%86%D0%B8%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F%20%D0%BC%D0%B0%D1%81%D1%81%D0%B8%D0%B2%D0%B0%0A%20%20%20%20nums%20%3D%20%5B1%2C%203%2C%202%2C%205%2C%204%5D%0A%20%20%20%20print%28%22%D0%9C%D0%B0%D1%81%D1%81%D0%B8%D0%B2%20nums%20%3D%22%2C%20nums%29%0A%0A%20%20%20%20%23%20%D0%A1%D0%BB%D1%83%D1%87%D0%B0%D0%B9%D0%BD%D1%8B%D0%B9%20%D0%B4%D0%BE%D1%81%D1%82%D1%83%D0%BF%0A%20%20%20%20random_num%3A%20int%20%3D%20random_access%28nums%29%0A%20%20%20%20print%28%22%D0%A1%D0%BB%D1%83%D1%87%D0%B0%D0%B9%D0%BD%D1%8B%D0%B9%20%D1%8D%D0%BB%D0%B5%D0%BC%D0%B5%D0%BD%D1%82%20%D0%B8%D0%B7%20nums%20%3D%22%2C%20random_num%29&codeDivHeight=800&codeDivWidth=600&cumulative=false&curInstr=7&heapPrimitives=nevernest&origin=opt-frontend.js&py=311&rawInputLstJSON=%5B%5D&textReferences=false" target="_blank" rel="noopener noreferrer">Во весь экран ></a></div></p>
|
||||
</details>
|
||||
<h3 id="3">3. Вставка элемента<a class="headerlink" href="#3" title="Permanent link">¶</a></h3>
|
||||
<p>Элементы массива в памяти расположены "вплотную" друг к другу, и между ними нет места для размещения новых данных. Как показано на рисунке 4-3, если мы хотим вставить элемент в середину массива, то все элементы после этой позиции нужно сдвинуть на одну позицию вправо, а затем записать новое значение в освободившийся индекс.</p>
|
||||
<p>Элементы массива в памяти расположены вплотную друг к другу, и между ними нет места для размещения новых данных. Как показано на рисунке 4-3, если мы хотим вставить элемент в середину массива, то все элементы после этой позиции нужно сдвинуть на одну позицию вправо, а затем записать новое значение в освободившийся индекс.</p>
|
||||
<p><img alt="Пример вставки элемента в массив" class="animation-figure" src="../array.assets/array_insert_element.png" /></p>
|
||||
<p align="center"> Рисунок 4-3 Пример вставки элемента в массив </p>
|
||||
|
||||
<p>Стоит отметить, что длина массива фиксирована, поэтому вставка нового элемента неизбежно приведет к "потере" элемента на конце массива. Решение этой проблемы мы оставим для обсуждения в разделе о "списках".</p>
|
||||
<p>Стоит отметить, что длина массива фиксирована, поэтому вставка нового элемента неизбежно приведет к потере элемента на конце массива. Решение этой проблемы мы оставим для обсуждения в разделе о "списках".</p>
|
||||
<div class="tabbed-set tabbed-alternate" data-tabs="3:13"><input checked="checked" id="__tabbed_3_1" name="__tabbed_3" type="radio" /><input id="__tabbed_3_2" name="__tabbed_3" type="radio" /><input id="__tabbed_3_3" name="__tabbed_3" type="radio" /><input id="__tabbed_3_4" name="__tabbed_3" type="radio" /><input id="__tabbed_3_5" name="__tabbed_3" type="radio" /><input id="__tabbed_3_6" name="__tabbed_3" type="radio" /><input id="__tabbed_3_7" name="__tabbed_3" type="radio" /><input id="__tabbed_3_8" name="__tabbed_3" type="radio" /><input id="__tabbed_3_9" name="__tabbed_3" type="radio" /><input id="__tabbed_3_10" name="__tabbed_3" type="radio" /><input id="__tabbed_3_11" name="__tabbed_3" type="radio" /><input id="__tabbed_3_12" name="__tabbed_3" type="radio" /><input id="__tabbed_3_13" name="__tabbed_3" type="radio" /><div class="tabbed-labels"><label for="__tabbed_3_1">Python</label><label for="__tabbed_3_2">C++</label><label for="__tabbed_3_3">Java</label><label for="__tabbed_3_4">C#</label><label for="__tabbed_3_5">Go</label><label for="__tabbed_3_6">Swift</label><label for="__tabbed_3_7">JS</label><label for="__tabbed_3_8">TS</label><label for="__tabbed_3_9">Dart</label><label for="__tabbed_3_10">Rust</label><label for="__tabbed_3_11">C</label><label for="__tabbed_3_12">Kotlin</label><label for="__tabbed_3_13">Ruby</label></div>
|
||||
<div class="tabbed-content">
|
||||
<div class="tabbed-block">
|
||||
@@ -4982,7 +4982,7 @@
|
||||
<p><img alt="Пример удаления элемента из массива" class="animation-figure" src="../array.assets/array_remove_element.png" /></p>
|
||||
<p align="center"> Рисунок 4-4 Пример удаления элемента из массива </p>
|
||||
|
||||
<p>Обрати внимание: после удаления исходный последний элемент становится "бессмысленным", поэтому специально изменять его не требуется.</p>
|
||||
<p>Обрати внимание: после удаления исходный последний элемент становится бессмысленным, поэтому специально изменять его не требуется.</p>
|
||||
<div class="tabbed-set tabbed-alternate" data-tabs="4:13"><input checked="checked" id="__tabbed_4_1" name="__tabbed_4" type="radio" /><input id="__tabbed_4_2" name="__tabbed_4" type="radio" /><input id="__tabbed_4_3" name="__tabbed_4" type="radio" /><input id="__tabbed_4_4" name="__tabbed_4" type="radio" /><input id="__tabbed_4_5" name="__tabbed_4" type="radio" /><input id="__tabbed_4_6" name="__tabbed_4" type="radio" /><input id="__tabbed_4_7" name="__tabbed_4" type="radio" /><input id="__tabbed_4_8" name="__tabbed_4" type="radio" /><input id="__tabbed_4_9" name="__tabbed_4" type="radio" /><input id="__tabbed_4_10" name="__tabbed_4" type="radio" /><input id="__tabbed_4_11" name="__tabbed_4" type="radio" /><input id="__tabbed_4_12" name="__tabbed_4" type="radio" /><input id="__tabbed_4_13" name="__tabbed_4" type="radio" /><div class="tabbed-labels"><label for="__tabbed_4_1">Python</label><label for="__tabbed_4_2">C++</label><label for="__tabbed_4_3">Java</label><label for="__tabbed_4_4">C#</label><label for="__tabbed_4_5">Go</label><label for="__tabbed_4_6">Swift</label><label for="__tabbed_4_7">JS</label><label for="__tabbed_4_8">TS</label><label for="__tabbed_4_9">Dart</label><label for="__tabbed_4_10">Rust</label><label for="__tabbed_4_11">C</label><label for="__tabbed_4_12">Kotlin</label><label for="__tabbed_4_13">Ruby</label></div>
|
||||
<div class="tabbed-content">
|
||||
<div class="tabbed-block">
|
||||
@@ -5125,7 +5125,7 @@
|
||||
<ul>
|
||||
<li><strong>Высокая временная сложность</strong>: средняя временная сложность и вставки, и удаления равна <span class="arithmatex">\(O(n)\)</span> , где <span class="arithmatex">\(n\)</span> - длина массива.</li>
|
||||
<li><strong>Потеря элементов</strong>: поскольку длина массива неизменяема, после вставки элементы, выходящие за пределы длины массива, будут потеряны.</li>
|
||||
<li><strong>Потери памяти</strong>: можно заранее инициализировать более длинный массив и использовать только его переднюю часть; тогда "теряемые" при вставке элементы на конце не будут нести смысла, но такой подход приводит к лишнему расходу памяти.</li>
|
||||
<li><strong>Потери памяти</strong>: можно заранее инициализировать более длинный массив и использовать только его переднюю часть; тогда теряемые при вставке элементы на конце не будут нести смысла, но такой подход приводит к лишнему расходу памяти.</li>
|
||||
</ul>
|
||||
<h3 id="5">5. Обход массива<a class="headerlink" href="#5" title="Permanent link">¶</a></h3>
|
||||
<p>В большинстве языков программирования массив можно обходить как по индексу, так и напрямую перебирая каждый элемент:</p>
|
||||
@@ -5346,7 +5346,7 @@
|
||||
</details>
|
||||
<h3 id="6">6. Поиск элемента<a class="headerlink" href="#6" title="Permanent link">¶</a></h3>
|
||||
<p>Чтобы найти заданный элемент в массиве, нужно пройти по массиву и на каждой итерации проверять, совпадает ли значение; если совпадает, вернуть соответствующий индекс.</p>
|
||||
<p>Поскольку массив - это линейная структура данных, такая операция поиска называется "линейным поиском".</p>
|
||||
<p>Поскольку массив - это линейная структура данных, такая операция поиска называется линейным поиском.</p>
|
||||
<div class="tabbed-set tabbed-alternate" data-tabs="6:13"><input checked="checked" id="__tabbed_6_1" name="__tabbed_6" type="radio" /><input id="__tabbed_6_2" name="__tabbed_6" type="radio" /><input id="__tabbed_6_3" name="__tabbed_6" type="radio" /><input id="__tabbed_6_4" name="__tabbed_6" type="radio" /><input id="__tabbed_6_5" name="__tabbed_6" type="radio" /><input id="__tabbed_6_6" name="__tabbed_6" type="radio" /><input id="__tabbed_6_7" name="__tabbed_6" type="radio" /><input id="__tabbed_6_8" name="__tabbed_6" type="radio" /><input id="__tabbed_6_9" name="__tabbed_6" type="radio" /><input id="__tabbed_6_10" name="__tabbed_6" type="radio" /><input id="__tabbed_6_11" name="__tabbed_6" type="radio" /><input id="__tabbed_6_12" name="__tabbed_6" type="radio" /><input id="__tabbed_6_13" name="__tabbed_6" type="radio" /><div class="tabbed-labels"><label for="__tabbed_6_1">Python</label><label for="__tabbed_6_2">C++</label><label for="__tabbed_6_3">Java</label><label for="__tabbed_6_4">C#</label><label for="__tabbed_6_5">Go</label><label for="__tabbed_6_6">Swift</label><label for="__tabbed_6_7">JS</label><label for="__tabbed_6_8">TS</label><label for="__tabbed_6_9">Dart</label><label for="__tabbed_6_10">Rust</label><label for="__tabbed_6_11">C</label><label for="__tabbed_6_12">Kotlin</label><label for="__tabbed_6_13">Ruby</label></div>
|
||||
<div class="tabbed-content">
|
||||
<div class="tabbed-block">
|
||||
@@ -5707,13 +5707,13 @@
|
||||
<div style="margin-top: 5px;"><a href="https://pythontutor.com/iframe-embed.html#code=%23%20%D0%9E%D0%B1%D1%80%D0%B0%D1%82%D0%B8%D1%82%D0%B5%20%D0%B2%D0%BD%D0%B8%D0%BC%D0%B0%D0%BD%D0%B8%D0%B5%3A%20list%20%D0%B2%20Python%20%E2%80%94%20%D1%8D%D1%82%D0%BE%20%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D0%B9%20%D0%BC%D0%B0%D1%81%D1%81%D0%B8%D0%B2%2C%20%D0%B5%D0%B3%D0%BE%20%D0%BC%D0%BE%D0%B6%D0%BD%D0%BE%20%D1%80%D0%B0%D1%81%D1%88%D0%B8%D1%80%D1%8F%D1%82%D1%8C%20%D0%BD%D0%B0%D0%BF%D1%80%D1%8F%D0%BC%D1%83%D1%8E%0A%23%20%D0%94%D0%BB%D1%8F%20%D1%83%D0%B4%D0%BE%D0%B1%D1%81%D1%82%D0%B2%D0%B0%20%D0%BE%D0%B1%D1%83%D1%87%D0%B5%D0%BD%D0%B8%D1%8F%20%D0%B2%20%D1%8D%D1%82%D0%BE%D0%B9%20%D1%84%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%B8%20list%20%D1%80%D0%B0%D1%81%D1%81%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D0%B2%D0%B0%D0%B5%D1%82%D1%81%D1%8F%20%D0%BA%D0%B0%D0%BA%20%D0%BC%D0%B0%D1%81%D1%81%D0%B8%D0%B2%20%D0%BD%D0%B5%D0%B8%D0%B7%D0%BC%D0%B5%D0%BD%D1%8F%D0%B5%D0%BC%D0%BE%D0%B9%20%D0%B4%D0%BB%D0%B8%D0%BD%D1%8B%0Adef%20extend%28nums%3A%20list%5Bint%5D%2C%20enlarge%3A%20int%29%20-%3E%20list%5Bint%5D%3A%0A%20%20%20%20%22%22%22%D0%A3%D0%B2%D0%B5%D0%BB%D0%B8%D1%87%D0%B8%D1%82%D1%8C%20%D0%B4%D0%BB%D0%B8%D0%BD%D1%83%20%D0%BC%D0%B0%D1%81%D1%81%D0%B8%D0%B2%D0%B0%22%22%22%0A%20%20%20%20%23%20%D0%98%D0%BD%D0%B8%D1%86%D0%B8%D0%B0%D0%BB%D0%B8%D0%B7%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D1%82%D1%8C%20%D0%BC%D0%B0%D1%81%D1%81%D0%B8%D0%B2%20%D1%83%D0%B2%D0%B5%D0%BB%D0%B8%D1%87%D0%B5%D0%BD%D0%BD%D0%BE%D0%B9%20%D0%B4%D0%BB%D0%B8%D0%BD%D1%8B%0A%20%20%20%20res%20%3D%20%5B0%5D%20%2A%20%28len%28nums%29%20%2B%20enlarge%29%0A%20%20%20%20%23%20%D0%A1%D0%BA%D0%BE%D0%BF%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D1%82%D1%8C%20%D0%B2%D1%81%D0%B5%20%D1%8D%D0%BB%D0%B5%D0%BC%D0%B5%D0%BD%D1%82%D1%8B%20%D0%B8%D1%81%D1%85%D0%BE%D0%B4%D0%BD%D0%BE%D0%B3%D0%BE%20%D0%BC%D0%B0%D1%81%D1%81%D0%B8%D0%B2%D0%B0%20%D0%B2%20%D0%BD%D0%BE%D0%B2%D1%8B%D0%B9%20%D0%BC%D0%B0%D1%81%D1%81%D0%B8%D0%B2%0A%20%20%20%20for%20i%20in%20range%28len%28nums%29%29%3A%0A%20%20%20%20%20%20%20%20res%5Bi%5D%20%3D%20nums%5Bi%5D%0A%20%20%20%20%23%20%D0%92%D0%B5%D1%80%D0%BD%D1%83%D1%82%D1%8C%20%D0%BD%D0%BE%D0%B2%D1%8B%D0%B9%20%D0%BC%D0%B0%D1%81%D1%81%D0%B8%D0%B2%20%D0%BF%D0%BE%D1%81%D0%BB%D0%B5%20%D1%80%D0%B0%D1%81%D1%88%D0%B8%D1%80%D0%B5%D0%BD%D0%B8%D1%8F%0A%20%20%20%20return%20res%0A%0A%22%22%22Driver%20Code%22%22%22%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20%23%20%D0%98%D0%BD%D0%B8%D1%86%D0%B8%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F%20%D0%BC%D0%B0%D1%81%D1%81%D0%B8%D0%B2%D0%B0%0A%20%20%20%20nums%20%3D%20%5B1%2C%203%2C%202%2C%205%2C%204%5D%0A%20%20%20%20print%28%22%D0%9C%D0%B0%D1%81%D1%81%D0%B8%D0%B2%20nums%20%3D%22%2C%20nums%29%0A%0A%20%20%20%20%23%20%D0%A0%D0%B0%D1%81%D1%88%D0%B8%D1%80%D0%B5%D0%BD%D0%B8%D0%B5%20%D0%B4%D0%BB%D0%B8%D0%BD%D1%8B%0A%20%20%20%20nums%20%3D%20extend%28nums%2C%203%29%0A%20%20%20%20print%28%22%D0%9F%D0%BE%D1%81%D0%BB%D0%B5%20%D1%83%D0%B2%D0%B5%D0%BB%D0%B8%D1%87%D0%B5%D0%BD%D0%B8%D1%8F%20%D0%B4%D0%BB%D0%B8%D0%BD%D1%8B%20%D0%BC%D0%B0%D1%81%D1%81%D0%B8%D0%B2%D0%B0%20%D0%B4%D0%BE%208%20nums%20%3D%22%2C%20nums%29&codeDivHeight=800&codeDivWidth=600&cumulative=false&curInstr=6&heapPrimitives=nevernest&origin=opt-frontend.js&py=311&rawInputLstJSON=%5B%5D&textReferences=false" target="_blank" rel="noopener noreferrer">Во весь экран ></a></div></p>
|
||||
</details>
|
||||
<h2 id="412">4.1.2 Преимущества и ограничения массива<a class="headerlink" href="#412" title="Permanent link">¶</a></h2>
|
||||
<p>Массив хранится в непрерывной области памяти, и все его элементы имеют один и тот же тип. Такой подход содержит много априорной информации, которую система может использовать для оптимизации эффективности операций со структурой данных.</p>
|
||||
<p>Массив хранится в непрерывной области памяти, и все его элементы имеют один и тот же тип. Такой подход содержит богатую априорную информацию, которую система может использовать для оптимизации эффективности операций с этой структурой данных.</p>
|
||||
<ul>
|
||||
<li><strong>Высокая пространственная эффективность</strong>: массив выделяет для данных непрерывный блок памяти без дополнительного структурного накладного расхода.</li>
|
||||
<li><strong>Поддержка произвольного доступа</strong>: массив позволяет обращаться к любому элементу за <span class="arithmatex">\(O(1)\)</span> времени.</li>
|
||||
<li><strong>Локальность кэша</strong>: при обращении к элементу массива компьютер загружает не только сам элемент, но и соседние данные, что позволяет использовать кэш для ускорения последующих операций.</li>
|
||||
</ul>
|
||||
<p>Хранение в непрерывной области памяти - палка о двух концах, и у него есть следующие ограничения.</p>
|
||||
<p>Непрерывное хранение данных - это палка о двух концах, и у него есть следующие ограничения.</p>
|
||||
<ul>
|
||||
<li><strong>Низкая эффективность вставки и удаления</strong>: когда элементов в массиве много, вставка и удаление требуют сдвига большого количества элементов.</li>
|
||||
<li><strong>Неизменяемая длина</strong>: после инициализации длина массива фиксирована; расширение массива требует копирования всех данных в новый массив, что стоит дорого.</li>
|
||||
@@ -5723,8 +5723,8 @@
|
||||
<p>Массив - это базовая и очень распространенная структура данных. Он часто используется как в различных алгоритмах, так и при реализации более сложных структур данных.</p>
|
||||
<ul>
|
||||
<li><strong>Произвольный доступ</strong>: если мы хотим случайным образом выбирать некоторые образцы, можно сохранить их в массиве и сгенерировать случайную последовательность индексов для выборки.</li>
|
||||
<li><strong>Сортировка и поиск</strong>: массив - самая распространенная структура данных для алгоритмов сортировки и поиска. Быстрая сортировка, сортировка слиянием, бинарный поиск и многие другие алгоритмы в основном работают именно с массивами.</li>
|
||||
<li><strong>Таблица поиска</strong>: когда нужно быстро находить элемент или его соответствие, массив можно использовать как lookup table. Например, если мы хотим реализовать отображение символов в коды ASCII, можно использовать значение ASCII как индекс, а соответствующий элемент хранить по этой позиции массива.</li>
|
||||
<li><strong>Сортировка и поиск</strong>: массив - самая распространенная структура данных для алгоритмов сортировки и поиска. Быстрая сортировка, сортировка слиянием, двоичный поиск и многие другие алгоритмы в основном работают именно с массивами.</li>
|
||||
<li><strong>Таблица поиска</strong>: когда нужно быстро находить элемент или его соответствие, массив можно использовать как таблицу поиска. Например, если мы хотим реализовать отображение символов в коды ASCII, можно использовать значение ASCII как индекс, а соответствующий элемент хранить по этой позиции массива.</li>
|
||||
<li><strong>Машинное обучение</strong>: в нейронных сетях широко используются операции линейной алгебры над векторами, матрицами и тензорами, и все эти данные строятся в форме массивов. Массив - самая часто используемая структура данных в программировании нейросетей.</li>
|
||||
<li><strong>Реализация структур данных</strong>: массивы можно использовать для реализации стеков, очередей, хеш-таблиц, куч, графов и других структур данных. Например, матрица смежности графа по сути является двумерным массивом.</li>
|
||||
</ul>
|
||||
|
||||
@@ -65,8 +65,8 @@
|
||||
|
||||
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Noto+Sans:300,300i,400,400i,500,500i,700,700i%7CJetBrains+Mono:400,400i,700,700i&display=fallback">
|
||||
<style>:root{--md-text-font:"Noto Sans";--md-code-font:"JetBrains Mono"}</style>
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=PT+Sans:300,300i,400,400i,500,500i,700,700i%7CJetBrains+Mono:400,400i,700,700i&display=fallback">
|
||||
<style>:root{--md-text-font:"PT Sans";--md-code-font:"JetBrains Mono"}</style>
|
||||
|
||||
|
||||
|
||||
@@ -574,7 +574,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
Глава 1. Знакомство с алгоритмами
|
||||
Глава 1. Введение в алгоритмы
|
||||
|
||||
|
||||
|
||||
@@ -596,7 +596,7 @@
|
||||
<span class="md-nav__icon md-icon"></span>
|
||||
|
||||
|
||||
Глава 1. Знакомство с алгоритмами
|
||||
Глава 1. Введение в алгоритмы
|
||||
|
||||
|
||||
</label>
|
||||
@@ -646,7 +646,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
1.2 Что такое структуры данных и алгоритмы
|
||||
1.2 Что такое алгоритм
|
||||
|
||||
|
||||
|
||||
@@ -1183,7 +1183,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
Глава 4. Массив и связный список
|
||||
Глава 4. Массивы и списки
|
||||
|
||||
|
||||
|
||||
@@ -1205,7 +1205,7 @@
|
||||
<span class="md-nav__icon md-icon"></span>
|
||||
|
||||
|
||||
Глава 4. Массив и связный список
|
||||
Глава 4. Массивы и списки
|
||||
|
||||
|
||||
</label>
|
||||
@@ -1311,7 +1311,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
4.4 Память и кеш *
|
||||
4.4 Оперативная память и кэш *
|
||||
|
||||
|
||||
|
||||
@@ -1593,7 +1593,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
Глава 6. Хеширование
|
||||
Глава 6. Хеш-таблицы
|
||||
|
||||
|
||||
|
||||
@@ -1615,7 +1615,7 @@
|
||||
<span class="md-nav__icon md-icon"></span>
|
||||
|
||||
|
||||
Глава 6. Хеширование
|
||||
Глава 6. Хеш-таблицы
|
||||
|
||||
|
||||
</label>
|
||||
@@ -1693,7 +1693,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
6.3 Хеш-алгоритмы
|
||||
6.3 Алгоритмы хеширования
|
||||
|
||||
|
||||
|
||||
@@ -1788,7 +1788,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
Глава 7. Дерево
|
||||
Глава 7. Деревья
|
||||
|
||||
|
||||
|
||||
@@ -1810,7 +1810,7 @@
|
||||
<span class="md-nav__icon md-icon"></span>
|
||||
|
||||
|
||||
Глава 7. Дерево
|
||||
Глава 7. Деревья
|
||||
|
||||
|
||||
</label>
|
||||
@@ -1888,7 +1888,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
7.3 Представление дерева массивом
|
||||
7.3 Представление двоичного дерева массивом
|
||||
|
||||
|
||||
|
||||
@@ -1972,7 +1972,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
7.6 Резюме
|
||||
7.6 Краткие итоги
|
||||
|
||||
|
||||
|
||||
@@ -2135,7 +2135,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
8.3 Задача Top-K
|
||||
8.3 Задача Top-k
|
||||
|
||||
|
||||
|
||||
@@ -2226,7 +2226,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
Глава 9. Граф
|
||||
Глава 9. Графы
|
||||
|
||||
|
||||
|
||||
@@ -2248,7 +2248,7 @@
|
||||
<span class="md-nav__icon md-icon"></span>
|
||||
|
||||
|
||||
Глава 9. Граф
|
||||
Глава 9. Графы
|
||||
|
||||
|
||||
</label>
|
||||
@@ -2298,7 +2298,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
9.2 Базовые операции над графами
|
||||
9.2 Базовые операции графа
|
||||
|
||||
|
||||
|
||||
@@ -2354,7 +2354,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
9.4 Резюме
|
||||
9.4 Краткие итоги
|
||||
|
||||
|
||||
|
||||
@@ -2493,7 +2493,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.2 Точка вставки двоичного поиска
|
||||
10.2 Двоичный поиск точки вставки
|
||||
|
||||
|
||||
|
||||
@@ -2521,7 +2521,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.3 Граничные случаи двоичного поиска
|
||||
10.3 Двоичный поиск границ
|
||||
|
||||
|
||||
|
||||
@@ -2549,7 +2549,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.4 Стратегия оптимизации через хеширование
|
||||
10.4 Стратегии оптимизации хеширования
|
||||
|
||||
|
||||
|
||||
@@ -2577,7 +2577,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.5 Алгоритмы поиска: новый взгляд
|
||||
10.5 Переосмысление алгоритмов поиска
|
||||
|
||||
|
||||
|
||||
@@ -2782,7 +2782,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
11.3 Пузырьковая сортировка
|
||||
11.3 Сортировка пузырьком
|
||||
|
||||
|
||||
|
||||
@@ -2810,7 +2810,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
11.4 Сортировка вставкой
|
||||
11.4 Сортировка вставками
|
||||
|
||||
|
||||
|
||||
@@ -3115,7 +3115,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
12.1 Алгоритмы разделяй и властвуй
|
||||
12.1 Стратегия разделяй и властвуй
|
||||
|
||||
|
||||
|
||||
@@ -3143,7 +3143,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
12.2 Стратегия поиска разделяй и властвуй
|
||||
12.2 Поисковая стратегия разделяй и властвуй
|
||||
|
||||
|
||||
|
||||
@@ -3420,7 +3420,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
13.4 Задача о $n$ ферзях
|
||||
13.4 Задача о n ферзях
|
||||
|
||||
|
||||
|
||||
@@ -3561,7 +3561,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
14.1 Введение в динамическое программирование
|
||||
14.1 Первое знакомство с динамическим программированием
|
||||
|
||||
|
||||
|
||||
@@ -3673,7 +3673,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
14.5 Задача о неограниченном рюкзаке
|
||||
14.5 Задача о полном рюкзаке
|
||||
|
||||
|
||||
|
||||
@@ -4278,14 +4278,14 @@
|
||||
<div class="admonition abstract">
|
||||
<p class="admonition-title">Abstract</p>
|
||||
<p>Мир структур данных напоминает прочную кирпичную стену.</p>
|
||||
<p>Кирпичи массива уложены ровно и плотно прилегают друг к другу. Кирпичи связного списка разбросаны в разных местах, а соединяющие их лозы свободно тянутся между щелями.</p>
|
||||
<p>Кирпичи массива уложены ровно и плотно прилегают друг к другу. Узлы связного списка, напротив, разбросаны в разных местах, а соединяющие их связи свободно тянутся между промежутками.</p>
|
||||
</div>
|
||||
<h2 id="_1">Содержание главы<a class="headerlink" href="#_1" title="Permanent link">¶</a></h2>
|
||||
<ul>
|
||||
<li><a href="array/">4.1 Массив</a></li>
|
||||
<li><a href="linked_list/">4.2 Связный список</a></li>
|
||||
<li><a href="list/">4.3 Список</a></li>
|
||||
<li><a href="ram_and_cache/">4.4 Память и кеш *</a></li>
|
||||
<li><a href="ram_and_cache/">4.4 Оперативная память и кэш *</a></li>
|
||||
<li><a href="summary/">4.5 Резюме</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
@@ -65,8 +65,8 @@
|
||||
|
||||
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Noto+Sans:300,300i,400,400i,500,500i,700,700i%7CJetBrains+Mono:400,400i,700,700i&display=fallback">
|
||||
<style>:root{--md-text-font:"Noto Sans";--md-code-font:"JetBrains Mono"}</style>
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=PT+Sans:300,300i,400,400i,500,500i,700,700i%7CJetBrains+Mono:400,400i,700,700i&display=fallback">
|
||||
<style>:root{--md-text-font:"PT Sans";--md-code-font:"JetBrains Mono"}</style>
|
||||
|
||||
|
||||
|
||||
@@ -574,7 +574,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
Глава 1. Знакомство с алгоритмами
|
||||
Глава 1. Введение в алгоритмы
|
||||
|
||||
|
||||
|
||||
@@ -596,7 +596,7 @@
|
||||
<span class="md-nav__icon md-icon"></span>
|
||||
|
||||
|
||||
Глава 1. Знакомство с алгоритмами
|
||||
Глава 1. Введение в алгоритмы
|
||||
|
||||
|
||||
</label>
|
||||
@@ -646,7 +646,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
1.2 Что такое структуры данных и алгоритмы
|
||||
1.2 Что такое алгоритм
|
||||
|
||||
|
||||
|
||||
@@ -1183,7 +1183,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
Глава 4. Массив и связный список
|
||||
Глава 4. Массивы и списки
|
||||
|
||||
|
||||
|
||||
@@ -1205,7 +1205,7 @@
|
||||
<span class="md-nav__icon md-icon"></span>
|
||||
|
||||
|
||||
Глава 4. Массив и связный список
|
||||
Глава 4. Массивы и списки
|
||||
|
||||
|
||||
</label>
|
||||
@@ -1464,7 +1464,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
4.4 Память и кеш *
|
||||
4.4 Оперативная память и кэш *
|
||||
|
||||
|
||||
|
||||
@@ -1746,7 +1746,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
Глава 6. Хеширование
|
||||
Глава 6. Хеш-таблицы
|
||||
|
||||
|
||||
|
||||
@@ -1768,7 +1768,7 @@
|
||||
<span class="md-nav__icon md-icon"></span>
|
||||
|
||||
|
||||
Глава 6. Хеширование
|
||||
Глава 6. Хеш-таблицы
|
||||
|
||||
|
||||
</label>
|
||||
@@ -1846,7 +1846,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
6.3 Хеш-алгоритмы
|
||||
6.3 Алгоритмы хеширования
|
||||
|
||||
|
||||
|
||||
@@ -1941,7 +1941,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
Глава 7. Дерево
|
||||
Глава 7. Деревья
|
||||
|
||||
|
||||
|
||||
@@ -1963,7 +1963,7 @@
|
||||
<span class="md-nav__icon md-icon"></span>
|
||||
|
||||
|
||||
Глава 7. Дерево
|
||||
Глава 7. Деревья
|
||||
|
||||
|
||||
</label>
|
||||
@@ -2041,7 +2041,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
7.3 Представление дерева массивом
|
||||
7.3 Представление двоичного дерева массивом
|
||||
|
||||
|
||||
|
||||
@@ -2125,7 +2125,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
7.6 Резюме
|
||||
7.6 Краткие итоги
|
||||
|
||||
|
||||
|
||||
@@ -2288,7 +2288,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
8.3 Задача Top-K
|
||||
8.3 Задача Top-k
|
||||
|
||||
|
||||
|
||||
@@ -2379,7 +2379,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
Глава 9. Граф
|
||||
Глава 9. Графы
|
||||
|
||||
|
||||
|
||||
@@ -2401,7 +2401,7 @@
|
||||
<span class="md-nav__icon md-icon"></span>
|
||||
|
||||
|
||||
Глава 9. Граф
|
||||
Глава 9. Графы
|
||||
|
||||
|
||||
</label>
|
||||
@@ -2451,7 +2451,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
9.2 Базовые операции над графами
|
||||
9.2 Базовые операции графа
|
||||
|
||||
|
||||
|
||||
@@ -2507,7 +2507,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
9.4 Резюме
|
||||
9.4 Краткие итоги
|
||||
|
||||
|
||||
|
||||
@@ -2646,7 +2646,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.2 Точка вставки двоичного поиска
|
||||
10.2 Двоичный поиск точки вставки
|
||||
|
||||
|
||||
|
||||
@@ -2674,7 +2674,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.3 Граничные случаи двоичного поиска
|
||||
10.3 Двоичный поиск границ
|
||||
|
||||
|
||||
|
||||
@@ -2702,7 +2702,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.4 Стратегия оптимизации через хеширование
|
||||
10.4 Стратегии оптимизации хеширования
|
||||
|
||||
|
||||
|
||||
@@ -2730,7 +2730,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.5 Алгоритмы поиска: новый взгляд
|
||||
10.5 Переосмысление алгоритмов поиска
|
||||
|
||||
|
||||
|
||||
@@ -2935,7 +2935,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
11.3 Пузырьковая сортировка
|
||||
11.3 Сортировка пузырьком
|
||||
|
||||
|
||||
|
||||
@@ -2963,7 +2963,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
11.4 Сортировка вставкой
|
||||
11.4 Сортировка вставками
|
||||
|
||||
|
||||
|
||||
@@ -3268,7 +3268,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
12.1 Алгоритмы разделяй и властвуй
|
||||
12.1 Стратегия разделяй и властвуй
|
||||
|
||||
|
||||
|
||||
@@ -3296,7 +3296,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
12.2 Стратегия поиска разделяй и властвуй
|
||||
12.2 Поисковая стратегия разделяй и властвуй
|
||||
|
||||
|
||||
|
||||
@@ -3573,7 +3573,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
13.4 Задача о $n$ ферзях
|
||||
13.4 Задача о n ферзях
|
||||
|
||||
|
||||
|
||||
@@ -3714,7 +3714,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
14.1 Введение в динамическое программирование
|
||||
14.1 Первое знакомство с динамическим программированием
|
||||
|
||||
|
||||
|
||||
@@ -3826,7 +3826,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
14.5 Задача о неограниченном рюкзаке
|
||||
14.5 Задача о полном рюкзаке
|
||||
|
||||
|
||||
|
||||
@@ -4521,17 +4521,17 @@
|
||||
|
||||
<!-- Page content -->
|
||||
<h1 id="42">4.2 Связный список<a class="headerlink" href="#42" title="Permanent link">¶</a></h1>
|
||||
<p>Память является общим ресурсом для всех программ, и в сложной среде выполнения свободные участки памяти могут быть разбросаны по всему адресу памяти. Мы знаем, что память для хранения массива должна быть непрерывной, а если массив очень велик, память может не суметь предоставить столь большой непрерывный блок. Именно здесь проявляется преимущество гибкости связного списка.</p>
|
||||
<p><u>Связный список (linked list)</u> - это линейная структура данных, в которой каждый элемент представляет собой объект-узел, а сами узлы соединены между собой через "ссылки". Ссылка хранит адрес памяти следующего узла, благодаря чему из текущего узла можно получить доступ к следующему.</p>
|
||||
<p>Конструкция связного списка позволяет хранить отдельные узлы в разных местах памяти, и их адреса вовсе не обязаны быть непрерывными.</p>
|
||||
<p>Память - общий ресурс для всех программ, и в сложной среде выполнения свободные участки памяти могут быть разбросаны по всему адресному пространству. Мы знаем, что память для хранения массива должна быть непрерывной, а если массив очень велик, в памяти может не оказаться столь большого непрерывного блока. Именно здесь и проявляется преимущество гибкости связного списка.</p>
|
||||
<p><u>Связный список (linked list)</u> - это линейная структура данных, в которой каждый элемент представляет собой объект-узел, а сами узлы соединены между собой с помощью ссылок. Ссылка хранит адрес памяти следующего узла, благодаря чему из текущего узла можно перейти к следующему.</p>
|
||||
<p>Конструкция связного списка позволяет хранить отдельные узлы в разных местах памяти, и их адреса вовсе не обязаны быть последовательными.</p>
|
||||
<p><img alt="Определение связного списка и способ хранения" class="animation-figure" src="../linked_list.assets/linkedlist_definition.png" /></p>
|
||||
<p align="center"> Рисунок 4-5 Определение связного списка и способ хранения </p>
|
||||
|
||||
<p>Если посмотреть на рисунок 4-5, можно заметить, что базовой единицей связного списка является объект <u>узел (node)</u>. Каждый узел содержит две части данных: "значение" узла и "ссылку" на следующий узел.</p>
|
||||
<p>Как видно на рисунке 4-5, базовой единицей связного списка является объект <u>узел (node)</u>. Каждый узел содержит две части данных: значение узла и ссылку на следующий узел.</p>
|
||||
<ul>
|
||||
<li>Первый узел связного списка называется "головным узлом", а последний - "хвостовым узлом".</li>
|
||||
<li>Хвостовой узел указывает на "пусто", что в Java, C++ и Python обозначается как <code>null</code> , <code>nullptr</code> и <code>None</code> соответственно.</li>
|
||||
<li>В языках, поддерживающих указатели, таких как C, C++, Go и Rust, упомянутую выше "ссылку" следует заменить на "указатель".</li>
|
||||
<li>Первый узел связного списка называется головным узлом, а последний - хвостовым узлом.</li>
|
||||
<li>Хвостовой узел указывает на пустое значение, что в Java, C++ и Python обозначается как <code>null</code> , <code>nullptr</code> и <code>None</code> соответственно.</li>
|
||||
<li>В языках, поддерживающих указатели, таких как C, C++, Go и Rust, упомянутую выше ссылку следует заменить на указатель.</li>
|
||||
</ul>
|
||||
<p>Как показано в коде ниже, узел связного списка <code>ListNode</code> хранит не только значение, но и дополнительную ссылку (указатель). Поэтому <strong>при одинаковом объеме данных связный список занимает больше памяти, чем массив</strong>.</p>
|
||||
<div class="tabbed-set tabbed-alternate" data-tabs="1:13"><input checked="checked" id="__tabbed_1_1" name="__tabbed_1" type="radio" /><input id="__tabbed_1_2" name="__tabbed_1" type="radio" /><input id="__tabbed_1_3" name="__tabbed_1" type="radio" /><input id="__tabbed_1_4" name="__tabbed_1" type="radio" /><input id="__tabbed_1_5" name="__tabbed_1" type="radio" /><input id="__tabbed_1_6" name="__tabbed_1" type="radio" /><input id="__tabbed_1_7" name="__tabbed_1" type="radio" /><input id="__tabbed_1_8" name="__tabbed_1" type="radio" /><input id="__tabbed_1_9" name="__tabbed_1" type="radio" /><input id="__tabbed_1_10" name="__tabbed_1" type="radio" /><input id="__tabbed_1_11" name="__tabbed_1" type="radio" /><input id="__tabbed_1_12" name="__tabbed_1" type="radio" /><input id="__tabbed_1_13" name="__tabbed_1" type="radio" /><div class="tabbed-labels"><label for="__tabbed_1_1">Python</label><label for="__tabbed_1_2">C++</label><label for="__tabbed_1_3">Java</label><label for="__tabbed_1_4">C#</label><label for="__tabbed_1_5">Go</label><label for="__tabbed_1_6">Swift</label><label for="__tabbed_1_7">JS</label><label for="__tabbed_1_8">TS</label><label for="__tabbed_1_9">Dart</label><label for="__tabbed_1_10">Rust</label><label for="__tabbed_1_11">C</label><label for="__tabbed_1_12">Kotlin</label><label for="__tabbed_1_13">Ruby</label></div>
|
||||
@@ -4577,7 +4577,7 @@
|
||||
<a id="__codelineno-4-4" name="__codelineno-4-4" href="#__codelineno-4-4"></a><span class="w"> </span><span class="nx">Next</span><span class="w"> </span><span class="o">*</span><span class="nx">ListNode</span><span class="w"> </span><span class="c1">// Указатель на следующий узел</span>
|
||||
<a id="__codelineno-4-5" name="__codelineno-4-5" href="#__codelineno-4-5"></a><span class="p">}</span>
|
||||
<a id="__codelineno-4-6" name="__codelineno-4-6" href="#__codelineno-4-6"></a>
|
||||
<a id="__codelineno-4-7" name="__codelineno-4-7" href="#__codelineno-4-7"></a><span class="c1">// NewListNode Конструктор, создает новый связный список</span>
|
||||
<a id="__codelineno-4-7" name="__codelineno-4-7" href="#__codelineno-4-7"></a><span class="c1">// NewListNode Конструктор, создает новый узел</span>
|
||||
<a id="__codelineno-4-8" name="__codelineno-4-8" href="#__codelineno-4-8"></a><span class="kd">func</span><span class="w"> </span><span class="nx">NewListNode</span><span class="p">(</span><span class="nx">val</span><span class="w"> </span><span class="kt">int</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="nx">ListNode</span><span class="w"> </span><span class="p">{</span>
|
||||
<a id="__codelineno-4-9" name="__codelineno-4-9" href="#__codelineno-4-9"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="o">&</span><span class="nx">ListNode</span><span class="p">{</span>
|
||||
<a id="__codelineno-4-10" name="__codelineno-4-10" href="#__codelineno-4-10"></a><span class="w"> </span><span class="nx">Val</span><span class="p">:</span><span class="w"> </span><span class="nx">val</span><span class="p">,</span>
|
||||
@@ -4683,7 +4683,7 @@
|
||||
</div>
|
||||
<h2 id="421">4.2.1 Основные операции со связным списком<a class="headerlink" href="#421" title="Permanent link">¶</a></h2>
|
||||
<h3 id="1">1. Инициализация связного списка<a class="headerlink" href="#1" title="Permanent link">¶</a></h3>
|
||||
<p>Построение связного списка состоит из двух шагов: сначала нужно инициализировать объекты всех узлов, затем установить связи-ссылки между ними. После завершения инициализации мы можем, начиная с головы списка, последовательно проходить все узлы по ссылке <code>next</code>.</p>
|
||||
<p>Построение связного списка состоит из двух шагов: сначала нужно инициализировать объекты всех узлов, затем установить ссылочные связи между ними. После завершения инициализации мы можем, начиная с головы списка, последовательно проходить все узлы по ссылке <code>next</code>.</p>
|
||||
<div class="tabbed-set tabbed-alternate" data-tabs="2:13"><input checked="checked" id="__tabbed_2_1" name="__tabbed_2" type="radio" /><input id="__tabbed_2_2" name="__tabbed_2" type="radio" /><input id="__tabbed_2_3" name="__tabbed_2" type="radio" /><input id="__tabbed_2_4" name="__tabbed_2" type="radio" /><input id="__tabbed_2_5" name="__tabbed_2" type="radio" /><input id="__tabbed_2_6" name="__tabbed_2" type="radio" /><input id="__tabbed_2_7" name="__tabbed_2" type="radio" /><input id="__tabbed_2_8" name="__tabbed_2" type="radio" /><input id="__tabbed_2_9" name="__tabbed_2" type="radio" /><input id="__tabbed_2_10" name="__tabbed_2" type="radio" /><input id="__tabbed_2_11" name="__tabbed_2" type="radio" /><input id="__tabbed_2_12" name="__tabbed_2" type="radio" /><input id="__tabbed_2_13" name="__tabbed_2" type="radio" /><div class="tabbed-labels"><label for="__tabbed_2_1">Python</label><label for="__tabbed_2_2">C++</label><label for="__tabbed_2_3">Java</label><label for="__tabbed_2_4">C#</label><label for="__tabbed_2_5">Go</label><label for="__tabbed_2_6">Swift</label><label for="__tabbed_2_7">JS</label><label for="__tabbed_2_8">TS</label><label for="__tabbed_2_9">Dart</label><label for="__tabbed_2_10">Rust</label><label for="__tabbed_2_11">C</label><label for="__tabbed_2_12">Kotlin</label><label for="__tabbed_2_13">Ruby</label></div>
|
||||
<div class="tabbed-content">
|
||||
<div class="tabbed-block">
|
||||
@@ -4888,10 +4888,10 @@
|
||||
<summary>Визуализация выполнения</summary>
|
||||
<p>https://pythontutor.com/render.html#code=class%20ListNode%3A%0A%20%20%20%20%22%22%22%D1%81%D0%B2%D1%8F%D0%B7%D0%BD%D1%8B%D0%B9%20%D1%81%D0%BF%D0%B8%D1%81%D0%BE%D0%BA%D1%83%D0%B7%D0%B5%D0%BB%D0%BA%D0%BB%D0%B0%D1%81%D1%81%22%22%22%0A%20%20%20%20def%20__init__%28self%2C%20val%3A%20int%29%3A%0A%20%20%20%20%20%20%20%20self.val%3A%20int%20%3D%20val%20%20%23%20%D0%97%D0%BD%D0%B0%D1%87%D0%B5%D0%BD%D0%B8%D0%B5%20%D1%83%D0%B7%D0%BB%D0%B0%0A%20%20%20%20%20%20%20%20self.next%3A%20ListNode%20%7C%20None%20%3D%20None%20%20%23%20%D0%A1%D1%81%D1%8B%D0%BB%D0%BA%D0%B0%20%D0%BD%D0%B0%20%D1%81%D0%BB%D0%B5%D0%B4%D1%83%D1%8E%D1%89%D0%B8%D0%B9%20%D1%83%D0%B7%D0%B5%D0%BB%0A%0A%22%22%22Driver%20Code%22%22%22%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20%23%20%D0%98%D0%BD%D0%B8%D1%86%D0%B8%D0%B0%D0%BB%D0%B8%D0%B7%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D1%82%D1%8C%20%D1%81%D0%B2%D1%8F%D0%B7%D0%BD%D1%8B%D0%B9%20%D1%81%D0%BF%D0%B8%D1%81%D0%BE%D0%BA%201%20-%3E%203%20-%3E%202%20-%3E%205%20-%3E%204%0A%20%20%20%20%23%20%D0%98%D0%BD%D0%B8%D1%86%D0%B8%D0%B0%D0%BB%D0%B8%D0%B7%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D1%82%D1%8C%20%D0%BA%D0%B0%D0%B6%D0%B4%D1%8B%D0%B9%20%D1%83%D0%B7%D0%B5%D0%BB%0A%20%20%20%20n0%20%3D%20ListNode%281%29%0A%20%20%20%20n1%20%3D%20ListNode%283%29%0A%20%20%20%20n2%20%3D%20ListNode%282%29%0A%20%20%20%20n3%20%3D%20ListNode%285%29%0A%20%20%20%20n4%20%3D%20ListNode%284%29%0A%20%20%20%20%23%20%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B8%D1%82%D1%8C%20%D1%81%D1%81%D1%8B%D0%BB%D0%BA%D0%B8%20%D0%BC%D0%B5%D0%B6%D0%B4%D1%83%20%D1%83%D0%B7%D0%BB%D0%B0%D0%BC%D0%B8%0A%20%20%20%20n0.next%20%3D%20n1%0A%20%20%20%20n1.next%20%3D%20n2%0A%20%20%20%20n2.next%20%3D%20n3%0A%20%20%20%20n3.next%20%3D%20n4&cumulative=false&curInstr=3&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=311&rawInputLstJSON=%5B%5D&textReferences=false</p>
|
||||
</details>
|
||||
<p>Массив в целом - это одна переменная: например, массив <code>nums</code> содержит элементы <code>nums[0]</code> , <code>nums[1]</code> и т.д. Связный список же состоит из множества независимых объектов-узлов. <strong>Обычно в качестве обозначения всего связного списка используют головной узел</strong>; например, в приведенном выше коде связный список можно обозначить как список <code>n0</code> .</p>
|
||||
<p>Массив в целом - это одна переменная: например, массив <code>nums</code> содержит элементы <code>nums[0]</code> , <code>nums[1]</code> и т.д. Связный список же состоит из множества независимых объектов-узлов. <strong>Обычно в качестве обозначения всего связного списка используют головной узел</strong>; например, в приведенном выше коде связный список можно обозначить как <code>n0</code> .</p>
|
||||
<h3 id="2">2. Вставка узла<a class="headerlink" href="#2" title="Permanent link">¶</a></h3>
|
||||
<p>Вставить узел в связный список очень легко. Как показано на рисунке 4-6, предположим, что мы хотим вставить новый узел <code>P</code> между двумя соседними узлами <code>n0</code> и <code>n1</code> ; <strong>для этого нужно изменить всего две ссылки (указателя)</strong>, а временная сложность будет равна <span class="arithmatex">\(O(1)\)</span> .</p>
|
||||
<p>Для сравнения: временная сложность вставки элемента в массив составляет <span class="arithmatex">\(O(n)\)</span> , и при большом объеме данных это неэффективно.</p>
|
||||
<p>Для сравнения: временная сложность вставки элемента в массив составляет <span class="arithmatex">\(O(n)\)</span> , и при большом объеме данных это менее эффективно.</p>
|
||||
<p><img alt="Пример вставки узла в связный список" class="animation-figure" src="../linked_list.assets/linkedlist_insert_node.png" /></p>
|
||||
<p align="center"> Рисунок 4-6 Пример вставки узла в связный список </p>
|
||||
|
||||
@@ -5023,8 +5023,8 @@
|
||||
<div style="margin-top: 5px;"><a href="https://pythontutor.com/iframe-embed.html#code=class%20ListNode%3A%0A%20%20%20%20%22%22%22%D0%9A%D0%BB%D0%B0%D1%81%D1%81%20%D1%83%D0%B7%D0%BB%D0%B0%20%D1%81%D0%B2%D1%8F%D0%B7%D0%BD%D0%BE%D0%B3%D0%BE%20%D1%81%D0%BF%D0%B8%D1%81%D0%BA%D0%B0%22%22%22%0A%20%20%20%20def%20__init__%28self%2C%20val%3A%20int%29%3A%0A%20%20%20%20%20%20%20%20self.val%3A%20int%20%3D%20val%20%20%23%20%D0%97%D0%BD%D0%B0%D1%87%D0%B5%D0%BD%D0%B8%D0%B5%20%D1%83%D0%B7%D0%BB%D0%B0%0A%20%20%20%20%20%20%20%20self.next%3A%20ListNode%20%7C%20None%20%3D%20None%20%20%23%20%D0%A1%D1%81%D1%8B%D0%BB%D0%BA%D0%B0%20%D0%BD%D0%B0%20%D1%83%D0%B7%D0%B5%D0%BB-%D0%BF%D1%80%D0%B5%D0%B5%D0%BC%D0%BD%D0%B8%D0%BA%0A%0Adef%20insert%28n0%3A%20ListNode%2C%20P%3A%20ListNode%29%3A%0A%20%20%20%20%22%22%22%D0%92%D1%81%D1%82%D0%B0%D0%B2%D0%B8%D1%82%D1%8C%20%D1%83%D0%B7%D0%B5%D0%BB%20P%20%D0%BF%D0%BE%D1%81%D0%BB%D0%B5%20%D1%83%D0%B7%D0%BB%D0%B0%20n0%20%D0%B2%20%D1%81%D0%B2%D1%8F%D0%B7%D0%BD%D0%BE%D0%BC%20%D1%81%D0%BF%D0%B8%D1%81%D0%BA%D0%B5%22%22%22%0A%20%20%20%20n1%20%3D%20n0.next%0A%20%20%20%20P.next%20%3D%20n1%0A%20%20%20%20n0.next%20%3D%20P%0A%0A%22%22%22Driver%20Code%22%22%22%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20%23%20%D0%98%D0%BD%D0%B8%D1%86%D0%B8%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F%20%D1%81%D0%B2%D1%8F%D0%B7%D0%BD%D0%BE%D0%B3%D0%BE%20%D1%81%D0%BF%D0%B8%D1%81%D0%BA%D0%B0%0A%20%20%20%20%23%20%D0%98%D0%BD%D0%B8%D1%86%D0%B8%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F%20%D0%B2%D1%81%D0%B5%D1%85%20%D1%83%D0%B7%D0%BB%D0%BE%D0%B2%0A%20%20%20%20n0%20%3D%20ListNode%281%29%0A%20%20%20%20n1%20%3D%20ListNode%283%29%0A%20%20%20%20n2%20%3D%20ListNode%282%29%0A%20%20%20%20n3%20%3D%20ListNode%285%29%0A%20%20%20%20n4%20%3D%20ListNode%284%29%0A%20%20%20%20%23%20%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B8%D1%82%D1%8C%20%D1%81%D1%81%D1%8B%D0%BB%D0%BA%D0%B8%20%D0%BC%D0%B5%D0%B6%D0%B4%D1%83%20%D1%83%D0%B7%D0%BB%D0%B0%D0%BC%D0%B8%0A%20%20%20%20n0.next%20%3D%20n1%0A%20%20%20%20n1.next%20%3D%20n2%0A%20%20%20%20n2.next%20%3D%20n3%0A%20%20%20%20n3.next%20%3D%20n4%0A%0A%20%20%20%20%23%20%D0%92%D1%81%D1%82%D0%B0%D0%B2%D0%BA%D0%B0%20%D1%83%D0%B7%D0%BB%D0%B0%0A%20%20%20%20p%20%3D%20ListNode%280%29%0A%20%20%20%20insert%28n0%2C%20p%29&codeDivHeight=800&codeDivWidth=600&cumulative=false&curInstr=39&heapPrimitives=nevernest&origin=opt-frontend.js&py=311&rawInputLstJSON=%5B%5D&textReferences=false" target="_blank" rel="noopener noreferrer">Во весь экран ></a></div></p>
|
||||
</details>
|
||||
<h3 id="3">3. Удаление узла<a class="headerlink" href="#3" title="Permanent link">¶</a></h3>
|
||||
<p>Как показано на рисунке 4-7, удалить узел из связного списка тоже очень удобно: <strong>нужно изменить всего одну ссылку (указатель)</strong>.</p>
|
||||
<p>Обрати внимание: хотя после завершения операции удаления узел <code>P</code> все еще указывает на <code>n1</code> , при обходе связного списка до <code>P</code> уже нельзя добраться, а значит <code>P</code> больше не принадлежит данному списку.</p>
|
||||
<p>Как показано на рисунке 4-7, удалить узел из связного списка тоже очень просто: <strong>нужно изменить всего одну ссылку (указатель)</strong>.</p>
|
||||
<p>Стоит отметить, что хотя после завершения операции удаления узел <code>P</code> все еще указывает на <code>n1</code> , при обходе связного списка до <code>P</code> уже нельзя добраться. Это означает, что <code>P</code> фактически больше не принадлежит данному списку.</p>
|
||||
<p><img alt="Удаление узла из связного списка" class="animation-figure" src="../linked_list.assets/linkedlist_remove_node.png" /></p>
|
||||
<p align="center"> Рисунок 4-7 Удаление узла из связного списка </p>
|
||||
|
||||
@@ -5200,7 +5200,7 @@
|
||||
<div style="margin-top: 5px;"><a href="https://pythontutor.com/iframe-embed.html#code=class%20ListNode%3A%0A%20%20%20%20%22%22%22%D0%9A%D0%BB%D0%B0%D1%81%D1%81%20%D1%83%D0%B7%D0%BB%D0%B0%20%D1%81%D0%B2%D1%8F%D0%B7%D0%BD%D0%BE%D0%B3%D0%BE%20%D1%81%D0%BF%D0%B8%D1%81%D0%BA%D0%B0%22%22%22%0A%20%20%20%20def%20__init__%28self%2C%20val%3A%20int%29%3A%0A%20%20%20%20%20%20%20%20self.val%3A%20int%20%3D%20val%20%20%23%20%D0%97%D0%BD%D0%B0%D1%87%D0%B5%D0%BD%D0%B8%D0%B5%20%D1%83%D0%B7%D0%BB%D0%B0%0A%20%20%20%20%20%20%20%20self.next%3A%20ListNode%20%7C%20None%20%3D%20None%20%20%23%20%D0%A1%D1%81%D1%8B%D0%BB%D0%BA%D0%B0%20%D0%BD%D0%B0%20%D1%83%D0%B7%D0%B5%D0%BB-%D0%BF%D1%80%D0%B5%D0%B5%D0%BC%D0%BD%D0%B8%D0%BA%0A%0Adef%20remove%28n0%3A%20ListNode%29%3A%0A%20%20%20%20%22%22%22%D0%A3%D0%B4%D0%B0%D0%BB%D0%B8%D1%82%D1%8C%20%D0%BF%D0%B5%D1%80%D0%B2%D1%8B%D0%B9%20%D1%83%D0%B7%D0%B5%D0%BB%20%D0%BF%D0%BE%D1%81%D0%BB%D0%B5%20%D1%83%D0%B7%D0%BB%D0%B0%20n0%20%D0%B2%20%D1%81%D0%B2%D1%8F%D0%B7%D0%BD%D0%BE%D0%BC%20%D1%81%D0%BF%D0%B8%D1%81%D0%BA%D0%B5%22%22%22%0A%20%20%20%20if%20not%20n0.next%3A%0A%20%20%20%20%20%20%20%20return%0A%20%20%20%20%23%20n0%20-%3E%20P%20-%3E%20n1%0A%20%20%20%20P%20%3D%20n0.next%0A%20%20%20%20n1%20%3D%20P.next%0A%20%20%20%20n0.next%20%3D%20n1%0A%0A%22%22%22Driver%20Code%22%22%22%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20%23%20%D0%98%D0%BD%D0%B8%D1%86%D0%B8%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F%20%D1%81%D0%B2%D1%8F%D0%B7%D0%BD%D0%BE%D0%B3%D0%BE%20%D1%81%D0%BF%D0%B8%D1%81%D0%BA%D0%B0%0A%20%20%20%20%23%20%D0%98%D0%BD%D0%B8%D1%86%D0%B8%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F%20%D0%B2%D1%81%D0%B5%D1%85%20%D1%83%D0%B7%D0%BB%D0%BE%D0%B2%0A%20%20%20%20n0%20%3D%20ListNode%281%29%0A%20%20%20%20n1%20%3D%20ListNode%283%29%0A%20%20%20%20n2%20%3D%20ListNode%282%29%0A%20%20%20%20n3%20%3D%20ListNode%285%29%0A%20%20%20%20n4%20%3D%20ListNode%284%29%0A%20%20%20%20%23%20%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B8%D1%82%D1%8C%20%D1%81%D1%81%D1%8B%D0%BB%D0%BA%D0%B8%20%D0%BC%D0%B5%D0%B6%D0%B4%D1%83%20%D1%83%D0%B7%D0%BB%D0%B0%D0%BC%D0%B8%0A%20%20%20%20n0.next%20%3D%20n1%0A%20%20%20%20n1.next%20%3D%20n2%0A%20%20%20%20n2.next%20%3D%20n3%0A%20%20%20%20n3.next%20%3D%20n4%0A%0A%20%20%20%20%23%20%D0%A3%D0%B4%D0%B0%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5%20%D1%83%D0%B7%D0%BB%D0%B0%0A%20%20%20%20remove%28n0%29&codeDivHeight=800&codeDivWidth=600&cumulative=false&curInstr=34&heapPrimitives=nevernest&origin=opt-frontend.js&py=311&rawInputLstJSON=%5B%5D&textReferences=false" target="_blank" rel="noopener noreferrer">Во весь экран ></a></div></p>
|
||||
</details>
|
||||
<h3 id="4">4. Доступ к узлу<a class="headerlink" href="#4" title="Permanent link">¶</a></h3>
|
||||
<p><strong>Доступ к узлам в связном списке менее эффективен</strong>. Как уже обсуждалось в предыдущем разделе, к любому элементу массива можно обратиться за <span class="arithmatex">\(O(1)\)</span> времени. Со связным списком это не так: программе нужно стартовать от головного узла и последовательно двигаться дальше, пока не будет найден целевой узел. То есть для доступа к <span class="arithmatex">\(i\)</span> -му узлу списка нужно выполнить <span class="arithmatex">\(i - 1\)</span> итераций, а временная сложность составляет <span class="arithmatex">\(O(n)\)</span> .</p>
|
||||
<p><strong>Доступ к узлам в связном списке менее эффективен</strong>. Как уже обсуждалось в предыдущем разделе, к любому элементу массива можно обратиться за <span class="arithmatex">\(O(1)\)</span> времени. Со связным списком это не так: программе нужно начать с головного узла и последовательно двигаться дальше, пока не будет найден целевой узел. То есть для доступа к <span class="arithmatex">\(i\)</span> -му узлу списка нужно выполнить <span class="arithmatex">\(i - 1\)</span> итераций, а временная сложность составляет <span class="arithmatex">\(O(n)\)</span> .</p>
|
||||
<div class="tabbed-set tabbed-alternate" data-tabs="5:13"><input checked="checked" id="__tabbed_5_1" name="__tabbed_5" type="radio" /><input id="__tabbed_5_2" name="__tabbed_5" type="radio" /><input id="__tabbed_5_3" name="__tabbed_5" type="radio" /><input id="__tabbed_5_4" name="__tabbed_5" type="radio" /><input id="__tabbed_5_5" name="__tabbed_5" type="radio" /><input id="__tabbed_5_6" name="__tabbed_5" type="radio" /><input id="__tabbed_5_7" name="__tabbed_5" type="radio" /><input id="__tabbed_5_8" name="__tabbed_5" type="radio" /><input id="__tabbed_5_9" name="__tabbed_5" type="radio" /><input id="__tabbed_5_10" name="__tabbed_5" type="radio" /><input id="__tabbed_5_11" name="__tabbed_5" type="radio" /><input id="__tabbed_5_12" name="__tabbed_5" type="radio" /><input id="__tabbed_5_13" name="__tabbed_5" type="radio" /><div class="tabbed-labels"><label for="__tabbed_5_1">Python</label><label for="__tabbed_5_2">C++</label><label for="__tabbed_5_3">Java</label><label for="__tabbed_5_4">C#</label><label for="__tabbed_5_5">Go</label><label for="__tabbed_5_6">Swift</label><label for="__tabbed_5_7">JS</label><label for="__tabbed_5_8">TS</label><label for="__tabbed_5_9">Dart</label><label for="__tabbed_5_10">Rust</label><label for="__tabbed_5_11">C</label><label for="__tabbed_5_12">Kotlin</label><label for="__tabbed_5_13">Ruby</label></div>
|
||||
<div class="tabbed-content">
|
||||
<div class="tabbed-block">
|
||||
@@ -5380,7 +5380,7 @@
|
||||
<div style="margin-top: 5px;"><a href="https://pythontutor.com/iframe-embed.html#code=class%20ListNode%3A%0A%20%20%20%20%22%22%22%D0%9A%D0%BB%D0%B0%D1%81%D1%81%20%D1%83%D0%B7%D0%BB%D0%B0%20%D1%81%D0%B2%D1%8F%D0%B7%D0%BD%D0%BE%D0%B3%D0%BE%20%D1%81%D0%BF%D0%B8%D1%81%D0%BA%D0%B0%22%22%22%0A%20%20%20%20def%20__init__%28self%2C%20val%3A%20int%29%3A%0A%20%20%20%20%20%20%20%20self.val%3A%20int%20%3D%20val%20%20%23%20%D0%97%D0%BD%D0%B0%D1%87%D0%B5%D0%BD%D0%B8%D0%B5%20%D1%83%D0%B7%D0%BB%D0%B0%0A%20%20%20%20%20%20%20%20self.next%3A%20ListNode%20%7C%20None%20%3D%20None%20%20%23%20%D0%A1%D1%81%D1%8B%D0%BB%D0%BA%D0%B0%20%D0%BD%D0%B0%20%D1%83%D0%B7%D0%B5%D0%BB-%D0%BF%D1%80%D0%B5%D0%B5%D0%BC%D0%BD%D0%B8%D0%BA%0A%0Adef%20access%28head%3A%20ListNode%2C%20index%3A%20int%29%20-%3E%20ListNode%20%7C%20None%3A%0A%20%20%20%20%22%22%22%D0%94%D0%BE%D1%81%D1%82%D1%83%D0%BF%20%D0%BA%20%D1%83%D0%B7%D0%BB%D1%83%20%D1%81%D0%B2%D1%8F%D0%B7%D0%BD%D0%BE%D0%B3%D0%BE%20%D1%81%D0%BF%D0%B8%D1%81%D0%BA%D0%B0%20%D0%BF%D0%BE%20%D0%B8%D0%BD%D0%B4%D0%B5%D0%BA%D1%81%D1%83%20index%22%22%22%0A%20%20%20%20for%20_%20in%20range%28index%29%3A%0A%20%20%20%20%20%20%20%20if%20not%20head%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20None%0A%20%20%20%20%20%20%20%20head%20%3D%20head.next%0A%20%20%20%20return%20head%0A%0A%22%22%22Driver%20Code%22%22%22%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20%23%20%D0%98%D0%BD%D0%B8%D1%86%D0%B8%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F%20%D1%81%D0%B2%D1%8F%D0%B7%D0%BD%D0%BE%D0%B3%D0%BE%20%D1%81%D0%BF%D0%B8%D1%81%D0%BA%D0%B0%0A%20%20%20%20%23%20%D0%98%D0%BD%D0%B8%D1%86%D0%B8%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F%20%D0%B2%D1%81%D0%B5%D1%85%20%D1%83%D0%B7%D0%BB%D0%BE%D0%B2%0A%20%20%20%20n0%20%3D%20ListNode%281%29%0A%20%20%20%20n1%20%3D%20ListNode%283%29%0A%20%20%20%20n2%20%3D%20ListNode%282%29%0A%20%20%20%20n3%20%3D%20ListNode%285%29%0A%20%20%20%20n4%20%3D%20ListNode%284%29%0A%20%20%20%20%23%20%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B8%D1%82%D1%8C%20%D1%81%D1%81%D1%8B%D0%BB%D0%BA%D0%B8%20%D0%BC%D0%B5%D0%B6%D0%B4%D1%83%20%D1%83%D0%B7%D0%BB%D0%B0%D0%BC%D0%B8%0A%20%20%20%20n0.next%20%3D%20n1%0A%20%20%20%20n1.next%20%3D%20n2%0A%20%20%20%20n2.next%20%3D%20n3%0A%20%20%20%20n3.next%20%3D%20n4%0A%0A%20%20%20%20%23%20%D0%94%D0%BE%D1%81%D1%82%D1%83%D0%BF%20%D0%BA%20%D1%83%D0%B7%D0%BB%D1%83%0A%20%20%20%20node%20%3D%20access%28n0%2C%203%29%0A%20%20%20%20print%28%22%D0%97%D0%BD%D0%B0%D1%87%D0%B5%D0%BD%D0%B8%D0%B5%20%D1%83%D0%B7%D0%BB%D0%B0%20%D0%BF%D0%BE%20%D0%B8%D0%BD%D0%B4%D0%B5%D0%BA%D1%81%D1%83%203%20%D0%B2%20%D1%81%D0%B2%D1%8F%D0%B7%D0%BD%D0%BE%D0%BC%20%D1%81%D0%BF%D0%B8%D1%81%D0%BA%D0%B5%20%3D%20%7B%7D%22.format%28node.val%29%29&codeDivHeight=800&codeDivWidth=600&cumulative=false&curInstr=34&heapPrimitives=nevernest&origin=opt-frontend.js&py=311&rawInputLstJSON=%5B%5D&textReferences=false" target="_blank" rel="noopener noreferrer">Во весь экран ></a></div></p>
|
||||
</details>
|
||||
<h3 id="5">5. Поиск узла<a class="headerlink" href="#5" title="Permanent link">¶</a></h3>
|
||||
<p>Выполни обход связного списка, найди в нем узел со значением <code>target</code> и верни индекс этого узла в списке. Этот процесс тоже относится к линейному поиску. Код выглядит следующим образом:</p>
|
||||
<p>Поиск узла заключается в обходе связного списка, нахождении узла со значением <code>target</code> и возврате его индекса в списке. Этот процесс тоже относится к линейному поиску. Код выглядит следующим образом:</p>
|
||||
<div class="tabbed-set tabbed-alternate" data-tabs="6:13"><input checked="checked" id="__tabbed_6_1" name="__tabbed_6" type="radio" /><input id="__tabbed_6_2" name="__tabbed_6" type="radio" /><input id="__tabbed_6_3" name="__tabbed_6" type="radio" /><input id="__tabbed_6_4" name="__tabbed_6" type="radio" /><input id="__tabbed_6_5" name="__tabbed_6" type="radio" /><input id="__tabbed_6_6" name="__tabbed_6" type="radio" /><input id="__tabbed_6_7" name="__tabbed_6" type="radio" /><input id="__tabbed_6_8" name="__tabbed_6" type="radio" /><input id="__tabbed_6_9" name="__tabbed_6" type="radio" /><input id="__tabbed_6_10" name="__tabbed_6" type="radio" /><input id="__tabbed_6_11" name="__tabbed_6" type="radio" /><input id="__tabbed_6_12" name="__tabbed_6" type="radio" /><input id="__tabbed_6_13" name="__tabbed_6" type="radio" /><div class="tabbed-labels"><label for="__tabbed_6_1">Python</label><label for="__tabbed_6_2">C++</label><label for="__tabbed_6_3">Java</label><label for="__tabbed_6_4">C#</label><label for="__tabbed_6_5">Go</label><label for="__tabbed_6_6">Swift</label><label for="__tabbed_6_7">JS</label><label for="__tabbed_6_8">TS</label><label for="__tabbed_6_9">Dart</label><label for="__tabbed_6_10">Rust</label><label for="__tabbed_6_11">C</label><label for="__tabbed_6_12">Kotlin</label><label for="__tabbed_6_13">Ruby</label></div>
|
||||
<div class="tabbed-content">
|
||||
<div class="tabbed-block">
|
||||
@@ -5631,9 +5631,9 @@
|
||||
<h2 id="423">4.2.3 Основные типы связных списков<a class="headerlink" href="#423" title="Permanent link">¶</a></h2>
|
||||
<p>Как показано на рисунке 4-8, существует три распространенных типа связных списков.</p>
|
||||
<ul>
|
||||
<li><strong>Односвязный список</strong>: это обычный связный список, рассмотренный выше. Узел односвязного списка содержит значение и ссылку на следующий узел. Первый узел называется головным, последний - хвостовым, и хвост указывает на пусто <code>None</code> .</li>
|
||||
<li><strong>Циклический список</strong>: если заставить хвостовой узел односвязного списка указывать на головной (то есть соединить хвост с головой), получится циклический список. В циклическом списке любой узел можно рассматривать как головной.</li>
|
||||
<li><strong>Двусвязный список</strong>: по сравнению с односвязным списком двусвязный хранит ссылки в двух направлениях. Определение узла двусвязного списка включает как ссылку на следующий узел, так и ссылку на предыдущий узел. По сравнению с односвязным списком двусвязный более гибок и позволяет проходить список в обе стороны, но за это приходится платить дополнительной памятью.</li>
|
||||
<li><strong>Односвязный список</strong>: это обычный связный список, рассмотренный выше. Узел односвязного списка содержит значение и ссылку на следующий узел. Первый узел называется головным, последний - хвостовым, и хвост указывает на <code>None</code> .</li>
|
||||
<li><strong>Циклический список</strong>: если заставить хвостовой узел односвязного списка указывать на головной, то есть соединить хвост с головой, получится циклический список. В циклическом списке любой узел можно рассматривать как головной.</li>
|
||||
<li><strong>Двусвязный список</strong>: по сравнению с односвязным списком двусвязный хранит ссылки в двух направлениях. Определение узла двусвязного списка включает как ссылку на следующий узел, так и ссылку на предыдущий узел. По сравнению с односвязным списком двусвязный более гибок и позволяет обходить список в обе стороны, но за это приходится платить дополнительной памятью.</li>
|
||||
</ul>
|
||||
<div class="tabbed-set tabbed-alternate" data-tabs="7:13"><input checked="checked" id="__tabbed_7_1" name="__tabbed_7" type="radio" /><input id="__tabbed_7_2" name="__tabbed_7" type="radio" /><input id="__tabbed_7_3" name="__tabbed_7" type="radio" /><input id="__tabbed_7_4" name="__tabbed_7" type="radio" /><input id="__tabbed_7_5" name="__tabbed_7" type="radio" /><input id="__tabbed_7_6" name="__tabbed_7" type="radio" /><input id="__tabbed_7_7" name="__tabbed_7" type="radio" /><input id="__tabbed_7_8" name="__tabbed_7" type="radio" /><input id="__tabbed_7_9" name="__tabbed_7" type="radio" /><input id="__tabbed_7_10" name="__tabbed_7" type="radio" /><input id="__tabbed_7_11" name="__tabbed_7" type="radio" /><input id="__tabbed_7_12" name="__tabbed_7" type="radio" /><input id="__tabbed_7_13" name="__tabbed_7" type="radio" /><div class="tabbed-labels"><label for="__tabbed_7_1">Python</label><label for="__tabbed_7_2">C++</label><label for="__tabbed_7_3">Java</label><label for="__tabbed_7_4">C#</label><label for="__tabbed_7_5">Go</label><label for="__tabbed_7_6">Swift</label><label for="__tabbed_7_7">JS</label><label for="__tabbed_7_8">TS</label><label for="__tabbed_7_9">Dart</label><label for="__tabbed_7_10">Rust</label><label for="__tabbed_7_11">C</label><label for="__tabbed_7_12">Kotlin</label><label for="__tabbed_7_13">Ruby</label></div>
|
||||
<div class="tabbed-content">
|
||||
@@ -5824,10 +5824,10 @@
|
||||
<p>Двусвязные списки обычно используются там, где нужен быстрый доступ как к предыдущему, так и к следующему элементу.</p>
|
||||
<ul>
|
||||
<li><strong>Продвинутые структуры данных</strong>: например, в красно-черных деревьях и B-деревьях нам нужен доступ к родительскому узлу; этого можно добиться, сохранив в узле ссылку на родителя, по аналогии с двусвязным списком.</li>
|
||||
<li><strong>История браузера</strong>: когда пользователь в браузере нажимает кнопки "вперед" или "назад", браузеру нужно знать предыдущую и следующую веб-страницы, которые он посещал. Свойства двусвязного списка делают такую операцию простой.</li>
|
||||
<li><strong>История браузера</strong>: когда пользователь в браузере нажимает кнопки "вперед" или "назад", браузеру нужно знать предыдущую и следующую посещенные страницы. Свойства двусвязного списка делают такую операцию простой.</li>
|
||||
<li><strong>Алгоритм LRU</strong>: в алгоритмах вытеснения из кэша (LRU) нужно быстро находить наименее недавно использованные данные, а также быстро добавлять и удалять узлы. Для этого двусвязный список подходит очень хорошо.</li>
|
||||
</ul>
|
||||
<p>Циклические списки часто применяются в сценариях, требующих периодических операций, например при планировании ресурсов в операционной системе.</p>
|
||||
<p>Циклические списки часто применяются в сценариях, требующих циклических операций, например при планировании ресурсов в операционной системе.</p>
|
||||
<ul>
|
||||
<li><strong>Алгоритм циклического распределения кванта времени</strong>: в операционных системах round-robin scheduling - это распространенный алгоритм планирования CPU, который циклически обходит набор процессов. Каждому процессу выделяется квант времени, и когда он исчерпан, CPU переключается на следующий процесс. Такую циклическую операцию удобно реализовать с помощью кольцевого списка.</li>
|
||||
<li><strong>Буферы данных</strong>: в некоторых реализациях буферов данных также могут использоваться циклические списки. Например, в аудио- и видеоплеерах поток данных может делиться на несколько буферных блоков и помещаться в кольцевой список для обеспечения непрерывного воспроизведения.</li>
|
||||
|
||||
@@ -65,8 +65,8 @@
|
||||
|
||||
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Noto+Sans:300,300i,400,400i,500,500i,700,700i%7CJetBrains+Mono:400,400i,700,700i&display=fallback">
|
||||
<style>:root{--md-text-font:"Noto Sans";--md-code-font:"JetBrains Mono"}</style>
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=PT+Sans:300,300i,400,400i,500,500i,700,700i%7CJetBrains+Mono:400,400i,700,700i&display=fallback">
|
||||
<style>:root{--md-text-font:"PT Sans";--md-code-font:"JetBrains Mono"}</style>
|
||||
|
||||
|
||||
|
||||
@@ -574,7 +574,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
Глава 1. Знакомство с алгоритмами
|
||||
Глава 1. Введение в алгоритмы
|
||||
|
||||
|
||||
|
||||
@@ -596,7 +596,7 @@
|
||||
<span class="md-nav__icon md-icon"></span>
|
||||
|
||||
|
||||
Глава 1. Знакомство с алгоритмами
|
||||
Глава 1. Введение в алгоритмы
|
||||
|
||||
|
||||
</label>
|
||||
@@ -646,7 +646,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
1.2 Что такое структуры данных и алгоритмы
|
||||
1.2 Что такое алгоритм
|
||||
|
||||
|
||||
|
||||
@@ -1183,7 +1183,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
Глава 4. Массив и связный список
|
||||
Глава 4. Массивы и списки
|
||||
|
||||
|
||||
|
||||
@@ -1205,7 +1205,7 @@
|
||||
<span class="md-nav__icon md-icon"></span>
|
||||
|
||||
|
||||
Глава 4. Массив и связный список
|
||||
Глава 4. Массивы и списки
|
||||
|
||||
|
||||
</label>
|
||||
@@ -1453,7 +1453,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
4.4 Память и кеш *
|
||||
4.4 Оперативная память и кэш *
|
||||
|
||||
|
||||
|
||||
@@ -1735,7 +1735,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
Глава 6. Хеширование
|
||||
Глава 6. Хеш-таблицы
|
||||
|
||||
|
||||
|
||||
@@ -1757,7 +1757,7 @@
|
||||
<span class="md-nav__icon md-icon"></span>
|
||||
|
||||
|
||||
Глава 6. Хеширование
|
||||
Глава 6. Хеш-таблицы
|
||||
|
||||
|
||||
</label>
|
||||
@@ -1835,7 +1835,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
6.3 Хеш-алгоритмы
|
||||
6.3 Алгоритмы хеширования
|
||||
|
||||
|
||||
|
||||
@@ -1930,7 +1930,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
Глава 7. Дерево
|
||||
Глава 7. Деревья
|
||||
|
||||
|
||||
|
||||
@@ -1952,7 +1952,7 @@
|
||||
<span class="md-nav__icon md-icon"></span>
|
||||
|
||||
|
||||
Глава 7. Дерево
|
||||
Глава 7. Деревья
|
||||
|
||||
|
||||
</label>
|
||||
@@ -2030,7 +2030,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
7.3 Представление дерева массивом
|
||||
7.3 Представление двоичного дерева массивом
|
||||
|
||||
|
||||
|
||||
@@ -2114,7 +2114,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
7.6 Резюме
|
||||
7.6 Краткие итоги
|
||||
|
||||
|
||||
|
||||
@@ -2277,7 +2277,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
8.3 Задача Top-K
|
||||
8.3 Задача Top-k
|
||||
|
||||
|
||||
|
||||
@@ -2368,7 +2368,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
Глава 9. Граф
|
||||
Глава 9. Графы
|
||||
|
||||
|
||||
|
||||
@@ -2390,7 +2390,7 @@
|
||||
<span class="md-nav__icon md-icon"></span>
|
||||
|
||||
|
||||
Глава 9. Граф
|
||||
Глава 9. Графы
|
||||
|
||||
|
||||
</label>
|
||||
@@ -2440,7 +2440,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
9.2 Базовые операции над графами
|
||||
9.2 Базовые операции графа
|
||||
|
||||
|
||||
|
||||
@@ -2496,7 +2496,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
9.4 Резюме
|
||||
9.4 Краткие итоги
|
||||
|
||||
|
||||
|
||||
@@ -2635,7 +2635,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.2 Точка вставки двоичного поиска
|
||||
10.2 Двоичный поиск точки вставки
|
||||
|
||||
|
||||
|
||||
@@ -2663,7 +2663,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.3 Граничные случаи двоичного поиска
|
||||
10.3 Двоичный поиск границ
|
||||
|
||||
|
||||
|
||||
@@ -2691,7 +2691,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.4 Стратегия оптимизации через хеширование
|
||||
10.4 Стратегии оптимизации хеширования
|
||||
|
||||
|
||||
|
||||
@@ -2719,7 +2719,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.5 Алгоритмы поиска: новый взгляд
|
||||
10.5 Переосмысление алгоритмов поиска
|
||||
|
||||
|
||||
|
||||
@@ -2924,7 +2924,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
11.3 Пузырьковая сортировка
|
||||
11.3 Сортировка пузырьком
|
||||
|
||||
|
||||
|
||||
@@ -2952,7 +2952,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
11.4 Сортировка вставкой
|
||||
11.4 Сортировка вставками
|
||||
|
||||
|
||||
|
||||
@@ -3257,7 +3257,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
12.1 Алгоритмы разделяй и властвуй
|
||||
12.1 Стратегия разделяй и властвуй
|
||||
|
||||
|
||||
|
||||
@@ -3285,7 +3285,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
12.2 Стратегия поиска разделяй и властвуй
|
||||
12.2 Поисковая стратегия разделяй и властвуй
|
||||
|
||||
|
||||
|
||||
@@ -3562,7 +3562,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
13.4 Задача о $n$ ферзях
|
||||
13.4 Задача о n ферзях
|
||||
|
||||
|
||||
|
||||
@@ -3703,7 +3703,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
14.1 Введение в динамическое программирование
|
||||
14.1 Первое знакомство с динамическим программированием
|
||||
|
||||
|
||||
|
||||
@@ -3815,7 +3815,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
14.5 Задача о неограниченном рюкзаке
|
||||
14.5 Задача о полном рюкзаке
|
||||
|
||||
|
||||
|
||||
@@ -4509,7 +4509,7 @@
|
||||
<p>На практике <strong>списки из стандартных библиотек многих языков программирования реализованы именно на основе динамических массивов</strong>, например <code>list</code> в Python, <code>ArrayList</code> в Java, <code>vector</code> в C++ и <code>List</code> в C#. В дальнейшем обсуждении мы будем считать понятия "список" и "динамический массив" эквивалентными.</p>
|
||||
<h2 id="431">4.3.1 Основные операции со списком<a class="headerlink" href="#431" title="Permanent link">¶</a></h2>
|
||||
<h3 id="1">1. Инициализация списка<a class="headerlink" href="#1" title="Permanent link">¶</a></h3>
|
||||
<p>Обычно мы используем два способа инициализации: "без начальных значений" и "с начальными значениями":</p>
|
||||
<p>Обычно используются два способа инициализации: без начальных значений и с начальными значениями:</p>
|
||||
<div class="tabbed-set tabbed-alternate" data-tabs="1:13"><input checked="checked" id="__tabbed_1_1" name="__tabbed_1" type="radio" /><input id="__tabbed_1_2" name="__tabbed_1" type="radio" /><input id="__tabbed_1_3" name="__tabbed_1" type="radio" /><input id="__tabbed_1_4" name="__tabbed_1" type="radio" /><input id="__tabbed_1_5" name="__tabbed_1" type="radio" /><input id="__tabbed_1_6" name="__tabbed_1" type="radio" /><input id="__tabbed_1_7" name="__tabbed_1" type="radio" /><input id="__tabbed_1_8" name="__tabbed_1" type="radio" /><input id="__tabbed_1_9" name="__tabbed_1" type="radio" /><input id="__tabbed_1_10" name="__tabbed_1" type="radio" /><input id="__tabbed_1_11" name="__tabbed_1" type="radio" /><input id="__tabbed_1_12" name="__tabbed_1" type="radio" /><input id="__tabbed_1_13" name="__tabbed_1" type="radio" /><div class="tabbed-labels"><label for="__tabbed_1_1">Python</label><label for="__tabbed_1_2">C++</label><label for="__tabbed_1_3">Java</label><label for="__tabbed_1_4">C#</label><label for="__tabbed_1_5">Go</label><label for="__tabbed_1_6">Swift</label><label for="__tabbed_1_7">JS</label><label for="__tabbed_1_8">TS</label><label for="__tabbed_1_9">Dart</label><label for="__tabbed_1_10">Rust</label><label for="__tabbed_1_11">C</label><label for="__tabbed_1_12">Kotlin</label><label for="__tabbed_1_13">Ruby</label></div>
|
||||
<div class="tabbed-content">
|
||||
<div class="tabbed-block">
|
||||
@@ -4623,7 +4623,7 @@
|
||||
<p>https://pythontutor.com/render.html#code=%22%22%22Driver%20Code%22%22%22%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20%23%20%D0%98%D0%BD%D0%B8%D1%86%D0%B8%D0%B0%D0%BB%D0%B8%D0%B7%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D1%82%D1%8C%20%D1%81%D0%BF%D0%B8%D1%81%D0%BE%D0%BA%0A%20%20%20%20%23%20%D0%91%D0%B5%D0%B7%20%D0%BD%D0%B0%D1%87%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D1%85%20%D0%B7%D0%BD%D0%B0%D1%87%D0%B5%D0%BD%D0%B8%D0%B9%0A%20%20%20%20nums1%20%3D%20%5B%5D%0A%20%20%20%20%23%20%D0%A1%20%D0%BD%D0%B0%D1%87%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%BC%D0%B8%20%D0%B7%D0%BD%D0%B0%D1%87%D0%B5%D0%BD%D0%B8%D1%8F%D0%BC%D0%B8%0A%20%20%20%20nums%20%3D%20%5B1%2C%203%2C%202%2C%205%2C%204%5D&cumulative=false&curInstr=4&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=311&rawInputLstJSON=%5B%5D&textReferences=false</p>
|
||||
</details>
|
||||
<h3 id="2">2. Доступ к элементам<a class="headerlink" href="#2" title="Permanent link">¶</a></h3>
|
||||
<p>Список по своей сути является массивом, поэтому доступ к элементам и их обновление можно выполнять за <span class="arithmatex">\(O(1)\)</span> времени, что очень эффективно.</p>
|
||||
<p>Поскольку в этом разделе список рассматривается как структура на основе динамического массива, доступ к элементам и их обновление можно выполнять за <span class="arithmatex">\(O(1)\)</span> времени, что очень эффективно.</p>
|
||||
<div class="tabbed-set tabbed-alternate" data-tabs="2:13"><input checked="checked" id="__tabbed_2_1" name="__tabbed_2" type="radio" /><input id="__tabbed_2_2" name="__tabbed_2" type="radio" /><input id="__tabbed_2_3" name="__tabbed_2" type="radio" /><input id="__tabbed_2_4" name="__tabbed_2" type="radio" /><input id="__tabbed_2_5" name="__tabbed_2" type="radio" /><input id="__tabbed_2_6" name="__tabbed_2" type="radio" /><input id="__tabbed_2_7" name="__tabbed_2" type="radio" /><input id="__tabbed_2_8" name="__tabbed_2" type="radio" /><input id="__tabbed_2_9" name="__tabbed_2" type="radio" /><input id="__tabbed_2_10" name="__tabbed_2" type="radio" /><input id="__tabbed_2_11" name="__tabbed_2" type="radio" /><input id="__tabbed_2_12" name="__tabbed_2" type="radio" /><input id="__tabbed_2_13" name="__tabbed_2" type="radio" /><div class="tabbed-labels"><label for="__tabbed_2_1">Python</label><label for="__tabbed_2_2">C++</label><label for="__tabbed_2_3">Java</label><label for="__tabbed_2_4">C#</label><label for="__tabbed_2_5">Go</label><label for="__tabbed_2_6">Swift</label><label for="__tabbed_2_7">JS</label><label for="__tabbed_2_8">TS</label><label for="__tabbed_2_9">Dart</label><label for="__tabbed_2_10">Rust</label><label for="__tabbed_2_11">C</label><label for="__tabbed_2_12">Kotlin</label><label for="__tabbed_2_13">Ruby</label></div>
|
||||
<div class="tabbed-content">
|
||||
<div class="tabbed-block">
|
||||
@@ -4730,7 +4730,7 @@
|
||||
<p>https://pythontutor.com/render.html#code=%22%22%22Driver%20Code%22%22%22%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20%23%20%D0%98%D0%BD%D0%B8%D1%86%D0%B8%D0%B0%D0%BB%D0%B8%D0%B7%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D1%82%D1%8C%20%D1%81%D0%BF%D0%B8%D1%81%D0%BE%D0%BA%0A%20%20%20%20nums%20%3D%20%5B1%2C%203%2C%202%2C%205%2C%204%5D%0A%0A%20%20%20%20%23%20%D0%9F%D0%BE%D0%BB%D1%83%D1%87%D0%B8%D1%82%D1%8C%20%D0%B4%D0%BE%D1%81%D1%82%D1%83%D0%BF%20%D0%BA%20%D1%8D%D0%BB%D0%B5%D0%BC%D0%B5%D0%BD%D1%82%D1%83%0A%20%20%20%20num%20%3D%20nums%5B1%5D%20%20%23%20%D0%BE%D0%B1%D1%80%D0%B0%D1%82%D0%B8%D1%82%D1%8C%D1%81%D1%8F%20%D0%BA%D0%B8%D0%BD%D0%B4%D0%B5%D0%BA%D1%81%201%20%D0%BF%D0%BE%D1%8D%D0%BB%D0%B5%D0%BC%D0%B5%D0%BD%D1%82%0A%0A%20%20%20%20%23%20%D0%9E%D0%B1%D0%BD%D0%BE%D0%B2%D0%B8%D1%82%D1%8C%20%D1%8D%D0%BB%D0%B5%D0%BC%D0%B5%D0%BD%D1%82%0A%20%20%20%20nums%5B1%5D%20%3D%200%20%20%20%20%23%20%D0%9E%D0%B1%D0%BD%D0%BE%D0%B2%D0%B8%D1%82%D1%8C%20%D1%8D%D0%BB%D0%B5%D0%BC%D0%B5%D0%BD%D1%82%20%D0%BF%D0%BE%20%D0%B8%D0%BD%D0%B4%D0%B5%D0%BA%D1%81%D1%83%201%20%D0%B4%D0%BE%200&cumulative=false&curInstr=3&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=311&rawInputLstJSON=%5B%5D&textReferences=false</p>
|
||||
</details>
|
||||
<h3 id="3">3. Вставка и удаление элементов<a class="headerlink" href="#3" title="Permanent link">¶</a></h3>
|
||||
<p>По сравнению с массивами список позволяет свободно добавлять и удалять элементы. Добавление элемента в конец списка имеет временную сложность <span class="arithmatex">\(O(1)\)</span> , но операции вставки и удаления по-прежнему имеют ту же эффективность, что и у массива, то есть <span class="arithmatex">\(O(n)\)</span> .</p>
|
||||
<p>В отличие от массива список позволяет свободно добавлять и удалять элементы. Добавление элемента в конец списка имеет временную сложность <span class="arithmatex">\(O(1)\)</span> , но операции вставки и удаления по-прежнему имеют ту же эффективность, что и у массива, то есть <span class="arithmatex">\(O(n)\)</span> .</p>
|
||||
<div class="tabbed-set tabbed-alternate" data-tabs="3:13"><input checked="checked" id="__tabbed_3_1" name="__tabbed_3" type="radio" /><input id="__tabbed_3_2" name="__tabbed_3" type="radio" /><input id="__tabbed_3_3" name="__tabbed_3" type="radio" /><input id="__tabbed_3_4" name="__tabbed_3" type="radio" /><input id="__tabbed_3_5" name="__tabbed_3" type="radio" /><input id="__tabbed_3_6" name="__tabbed_3" type="radio" /><input id="__tabbed_3_7" name="__tabbed_3" type="radio" /><input id="__tabbed_3_8" name="__tabbed_3" type="radio" /><input id="__tabbed_3_9" name="__tabbed_3" type="radio" /><input id="__tabbed_3_10" name="__tabbed_3" type="radio" /><input id="__tabbed_3_11" name="__tabbed_3" type="radio" /><input id="__tabbed_3_12" name="__tabbed_3" type="radio" /><input id="__tabbed_3_13" name="__tabbed_3" type="radio" /><div class="tabbed-labels"><label for="__tabbed_3_1">Python</label><label for="__tabbed_3_2">C++</label><label for="__tabbed_3_3">Java</label><label for="__tabbed_3_4">C#</label><label for="__tabbed_3_5">Go</label><label for="__tabbed_3_6">Swift</label><label for="__tabbed_3_7">JS</label><label for="__tabbed_3_8">TS</label><label for="__tabbed_3_9">Dart</label><label for="__tabbed_3_10">Rust</label><label for="__tabbed_3_11">C</label><label for="__tabbed_3_12">Kotlin</label><label for="__tabbed_3_13">Ruby</label></div>
|
||||
<div class="tabbed-content">
|
||||
<div class="tabbed-block">
|
||||
@@ -5137,7 +5137,7 @@
|
||||
<p>https://pythontutor.com/render.html#code=%22%22%22Driver%20Code%22%22%22%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20%23%20%D0%98%D0%BD%D0%B8%D1%86%D0%B8%D0%B0%D0%BB%D0%B8%D0%B7%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D1%82%D1%8C%20%D1%81%D0%BF%D0%B8%D1%81%D0%BE%D0%BA%0A%20%20%20%20nums%20%3D%20%5B1%2C%203%2C%202%2C%205%2C%204%5D%0A%20%20%20%20%0A%20%20%20%20%23%20%D0%9E%D0%B1%D1%85%D0%BE%D0%B4%D0%B8%D1%82%D1%8C%20%D1%81%D0%BF%D0%B8%D1%81%D0%BE%D0%BA%20%D0%BF%D0%BE%20%D0%B8%D0%BD%D0%B4%D0%B5%D0%BA%D1%81%D0%B0%D0%BC%0A%20%20%20%20count%20%3D%200%0A%20%20%20%20for%20i%20in%20range%28len%28nums%29%29%3A%0A%20%20%20%20%20%20%20%20count%20%2B%3D%20nums%5Bi%5D%0A%0A%20%20%20%20%23%20%D0%9D%D0%B5%D0%BF%D0%BE%D1%81%D1%80%D0%B5%D0%B4%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D0%BE%20%D0%BE%D0%B1%D1%85%D0%BE%D0%B4%D0%B8%D1%82%D1%8C%20%D1%8D%D0%BB%D0%B5%D0%BC%D0%B5%D0%BD%D1%82%D1%8B%20%D1%81%D0%BF%D0%B8%D1%81%D0%BA%D0%B0%0A%20%20%20%20for%20num%20in%20nums%3A%0A%20%20%20%20%20%20%20%20count%20%2B%3D%20num&cumulative=false&curInstr=3&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=311&rawInputLstJSON=%5B%5D&textReferences=false</p>
|
||||
</details>
|
||||
<h3 id="5">5. Конкатенация списков<a class="headerlink" href="#5" title="Permanent link">¶</a></h3>
|
||||
<p>Если дан новый список <code>nums1</code> , мы можем присоединить его к хвосту исходного списка.</p>
|
||||
<p>Создав новый список <code>nums1</code> , мы можем присоединить его к хвосту исходного списка.</p>
|
||||
<div class="tabbed-set tabbed-alternate" data-tabs="5:13"><input checked="checked" id="__tabbed_5_1" name="__tabbed_5" type="radio" /><input id="__tabbed_5_2" name="__tabbed_5" type="radio" /><input id="__tabbed_5_3" name="__tabbed_5" type="radio" /><input id="__tabbed_5_4" name="__tabbed_5" type="radio" /><input id="__tabbed_5_5" name="__tabbed_5" type="radio" /><input id="__tabbed_5_6" name="__tabbed_5" type="radio" /><input id="__tabbed_5_7" name="__tabbed_5" type="radio" /><input id="__tabbed_5_8" name="__tabbed_5" type="radio" /><input id="__tabbed_5_9" name="__tabbed_5" type="radio" /><input id="__tabbed_5_10" name="__tabbed_5" type="radio" /><input id="__tabbed_5_11" name="__tabbed_5" type="radio" /><input id="__tabbed_5_12" name="__tabbed_5" type="radio" /><input id="__tabbed_5_13" name="__tabbed_5" type="radio" /><div class="tabbed-labels"><label for="__tabbed_5_1">Python</label><label for="__tabbed_5_2">C++</label><label for="__tabbed_5_3">Java</label><label for="__tabbed_5_4">C#</label><label for="__tabbed_5_5">Go</label><label for="__tabbed_5_6">Swift</label><label for="__tabbed_5_7">JS</label><label for="__tabbed_5_8">TS</label><label for="__tabbed_5_9">Dart</label><label for="__tabbed_5_10">Rust</label><label for="__tabbed_5_11">C</label><label for="__tabbed_5_12">Kotlin</label><label for="__tabbed_5_13">Ruby</label></div>
|
||||
<div class="tabbed-content">
|
||||
<div class="tabbed-block">
|
||||
@@ -5224,7 +5224,7 @@
|
||||
<p>https://pythontutor.com/render.html#code=%22%22%22Driver%20Code%22%22%22%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20%23%20%D0%98%D0%BD%D0%B8%D1%86%D0%B8%D0%B0%D0%BB%D0%B8%D0%B7%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D1%82%D1%8C%20%D1%81%D0%BF%D0%B8%D1%81%D0%BE%D0%BA%0A%20%20%20%20nums%20%3D%20%5B1%2C%203%2C%202%2C%205%2C%204%5D%0A%20%20%20%20%0A%20%20%20%20%23%20%D0%9E%D0%B1%D1%8A%D0%B5%D0%B4%D0%B8%D0%BD%D0%B8%D1%82%D1%8C%20%D0%B4%D0%B2%D0%B0%20%D1%81%D0%BF%D0%B8%D1%81%D0%BA%D0%B0%0A%20%20%20%20nums1%20%3D%20%5B6%2C%208%2C%207%2C%2010%2C%209%5D%0A%20%20%20%20nums%20%2B%3D%20nums1%20%20%23%20%D0%9F%D1%80%D0%B8%D1%81%D0%BE%D0%B5%D0%B4%D0%B8%D0%BD%D0%B8%D1%82%D1%8C%20%D1%81%D0%BF%D0%B8%D1%81%D0%BE%D0%BA%20nums1%20%D0%BA%20nums&cumulative=false&curInstr=3&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=311&rawInputLstJSON=%5B%5D&textReferences=false</p>
|
||||
</details>
|
||||
<h3 id="6">6. Сортировка списка<a class="headerlink" href="#6" title="Permanent link">¶</a></h3>
|
||||
<p>После сортировки списка мы сможем применять алгоритмы "бинарный поиск" и "два указателя", которые очень часто встречаются в задачах по массивам.</p>
|
||||
<p>После сортировки списка мы сможем применять алгоритмы "двоичный поиск" и "два указателя", которые очень часто встречаются в задачах по массивам.</p>
|
||||
<div class="tabbed-set tabbed-alternate" data-tabs="6:13"><input checked="checked" id="__tabbed_6_1" name="__tabbed_6" type="radio" /><input id="__tabbed_6_2" name="__tabbed_6" type="radio" /><input id="__tabbed_6_3" name="__tabbed_6" type="radio" /><input id="__tabbed_6_4" name="__tabbed_6" type="radio" /><input id="__tabbed_6_5" name="__tabbed_6" type="radio" /><input id="__tabbed_6_6" name="__tabbed_6" type="radio" /><input id="__tabbed_6_7" name="__tabbed_6" type="radio" /><input id="__tabbed_6_8" name="__tabbed_6" type="radio" /><input id="__tabbed_6_9" name="__tabbed_6" type="radio" /><input id="__tabbed_6_10" name="__tabbed_6" type="radio" /><input id="__tabbed_6_11" name="__tabbed_6" type="radio" /><input id="__tabbed_6_12" name="__tabbed_6" type="radio" /><input id="__tabbed_6_13" name="__tabbed_6" type="radio" /><div class="tabbed-labels"><label for="__tabbed_6_1">Python</label><label for="__tabbed_6_2">C++</label><label for="__tabbed_6_3">Java</label><label for="__tabbed_6_4">C#</label><label for="__tabbed_6_5">Go</label><label for="__tabbed_6_6">Swift</label><label for="__tabbed_6_7">JS</label><label for="__tabbed_6_8">TS</label><label for="__tabbed_6_9">Dart</label><label for="__tabbed_6_10">Rust</label><label for="__tabbed_6_11">C</label><label for="__tabbed_6_12">Kotlin</label><label for="__tabbed_6_13">Ruby</label></div>
|
||||
<div class="tabbed-content">
|
||||
<div class="tabbed-block">
|
||||
@@ -5298,11 +5298,11 @@
|
||||
<p>https://pythontutor.com/render.html#code=%22%22%22Driver%20Code%22%22%22%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20%23%20%D0%98%D0%BD%D0%B8%D1%86%D0%B8%D0%B0%D0%BB%D0%B8%D0%B7%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D1%82%D1%8C%20%D1%81%D0%BF%D0%B8%D1%81%D0%BE%D0%BA%0A%20%20%20%20nums%20%3D%20%5B1%2C%203%2C%202%2C%205%2C%204%5D%0A%20%20%20%20%0A%20%20%20%20%23%20%D0%9E%D1%82%D1%81%D0%BE%D1%80%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D1%82%D1%8C%20%D1%81%D0%BF%D0%B8%D1%81%D0%BE%D0%BA%0A%20%20%20%20nums.sort%28%29%20%20%23%20%D0%A1%D0%BE%D1%80%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%BA%D0%B0%D0%BF%D0%BE%D1%81%D0%BB%D0%B5%2C%20%D1%81%D0%BF%D0%B8%D1%81%D0%BE%D0%BA%D1%8D%D0%BB%D0%B5%D0%BC%D0%B5%D0%BD%D1%82%D1%80%D0%B0%D1%81%D0%BF%D0%BE%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D1%8B%20%D0%BF%D0%BE%20%D0%B2%D0%BE%D0%B7%D1%80%D0%B0%D1%81%D1%82%D0%B0%D0%BD%D0%B8%D1%8E&cumulative=false&curInstr=3&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=311&rawInputLstJSON=%5B%5D&textReferences=false</p>
|
||||
</details>
|
||||
<h2 id="432">4.3.2 Реализация списка<a class="headerlink" href="#432" title="Permanent link">¶</a></h2>
|
||||
<p>Во многих языках программирования списки встроены в стандартную библиотеку, например в Java, C++ и Python. Их реализация довольно сложна, а настройки параметров тщательно продуманы: начальная емкость, коэффициент расширения и так далее. Если тебе интересно, стоит заглянуть в исходный код.</p>
|
||||
<p>Во многих языках программирования списки встроены в стандартную библиотеку, например в Java, C++, Python и других языках. Их реализация довольно сложна, а настройки параметров тщательно продуманы: начальная емкость, коэффициент расширения и так далее. Если это интересно, стоит заглянуть в исходный код.</p>
|
||||
<p>Чтобы лучше понять принцип работы списка, попробуем реализовать его упрощенную версию, в которой есть три ключевых аспекта проектирования.</p>
|
||||
<ul>
|
||||
<li><strong>Начальная емкость</strong>: выбрать разумную начальную емкость внутреннего массива. В этом примере мы берем 10.</li>
|
||||
<li><strong>Учет количества элементов</strong>: объявить переменную <code>size</code> , которая будет хранить текущее число элементов в списке и обновляться в реальном времени при вставке и удалении элементов. С помощью этой переменной можно находить конец списка и понимать, требуется ли расширение.</li>
|
||||
<li><strong>Учет количества элементов</strong>: объявить переменную <code>size</code> , которая будет хранить текущее число элементов в списке и обновляться в реальном времени при вставке и удалении элементов. С помощью этой переменной можно определять конец списка и понимать, требуется ли расширение.</li>
|
||||
<li><strong>Механизм расширения</strong>: если при вставке элементов емкость списка исчерпана, нужно выполнить расширение. Для этого сначала создается больший массив с учетом коэффициента расширения, а затем все элементы текущего массива по порядку переносятся в новый. В этом примере мы считаем, что каждый раз массив расширяется в 2 раза.</li>
|
||||
</ul>
|
||||
<div class="tabbed-set tabbed-alternate" data-tabs="7:13"><input checked="checked" id="__tabbed_7_1" name="__tabbed_7" type="radio" /><input id="__tabbed_7_2" name="__tabbed_7" type="radio" /><input id="__tabbed_7_3" name="__tabbed_7" type="radio" /><input id="__tabbed_7_4" name="__tabbed_7" type="radio" /><input id="__tabbed_7_5" name="__tabbed_7" type="radio" /><input id="__tabbed_7_6" name="__tabbed_7" type="radio" /><input id="__tabbed_7_7" name="__tabbed_7" type="radio" /><input id="__tabbed_7_8" name="__tabbed_7" type="radio" /><input id="__tabbed_7_9" name="__tabbed_7" type="radio" /><input id="__tabbed_7_10" name="__tabbed_7" type="radio" /><input id="__tabbed_7_11" name="__tabbed_7" type="radio" /><input id="__tabbed_7_12" name="__tabbed_7" type="radio" /><input id="__tabbed_7_13" name="__tabbed_7" type="radio" /><div class="tabbed-labels"><label for="__tabbed_7_1">Python</label><label for="__tabbed_7_2">C++</label><label for="__tabbed_7_3">Java</label><label for="__tabbed_7_4">C#</label><label for="__tabbed_7_5">Go</label><label for="__tabbed_7_6">Swift</label><label for="__tabbed_7_7">JS</label><label for="__tabbed_7_8">TS</label><label for="__tabbed_7_9">Dart</label><label for="__tabbed_7_10">Rust</label><label for="__tabbed_7_11">C</label><label for="__tabbed_7_12">Kotlin</label><label for="__tabbed_7_13">Ruby</label></div>
|
||||
@@ -6663,7 +6663,7 @@ aria-label="Нижний колонтитул"
|
||||
<a
|
||||
href="../ram_and_cache/"
|
||||
class="md-footer__link md-footer__link--next"
|
||||
aria-label="Вперед: 4.4 Память и кеш *"
|
||||
aria-label="Вперед: 4.4 Оперативная память и кэш *"
|
||||
rel="next"
|
||||
>
|
||||
<div class="md-footer__title">
|
||||
@@ -6671,7 +6671,7 @@ aria-label="Нижний колонтитул"
|
||||
Вперед
|
||||
</span>
|
||||
<div class="md-ellipsis">
|
||||
4.4 Память и кеш *
|
||||
4.4 Оперативная память и кэш *
|
||||
</div>
|
||||
</div>
|
||||
<div class="md-footer__button md-icon">
|
||||
|
||||
@@ -65,8 +65,8 @@
|
||||
|
||||
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Noto+Sans:300,300i,400,400i,500,500i,700,700i%7CJetBrains+Mono:400,400i,700,700i&display=fallback">
|
||||
<style>:root{--md-text-font:"Noto Sans";--md-code-font:"JetBrains Mono"}</style>
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=PT+Sans:300,300i,400,400i,500,500i,700,700i%7CJetBrains+Mono:400,400i,700,700i&display=fallback">
|
||||
<style>:root{--md-text-font:"PT Sans";--md-code-font:"JetBrains Mono"}</style>
|
||||
|
||||
|
||||
|
||||
@@ -574,7 +574,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
Глава 1. Знакомство с алгоритмами
|
||||
Глава 1. Введение в алгоритмы
|
||||
|
||||
|
||||
|
||||
@@ -596,7 +596,7 @@
|
||||
<span class="md-nav__icon md-icon"></span>
|
||||
|
||||
|
||||
Глава 1. Знакомство с алгоритмами
|
||||
Глава 1. Введение в алгоритмы
|
||||
|
||||
|
||||
</label>
|
||||
@@ -646,7 +646,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
1.2 Что такое структуры данных и алгоритмы
|
||||
1.2 Что такое алгоритм
|
||||
|
||||
|
||||
|
||||
@@ -1183,7 +1183,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
Глава 4. Массив и связный список
|
||||
Глава 4. Массивы и списки
|
||||
|
||||
|
||||
|
||||
@@ -1205,7 +1205,7 @@
|
||||
<span class="md-nav__icon md-icon"></span>
|
||||
|
||||
|
||||
Глава 4. Массив и связный список
|
||||
Глава 4. Массивы и списки
|
||||
|
||||
|
||||
</label>
|
||||
@@ -1320,7 +1320,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
4.4 Память и кеш *
|
||||
4.4 Оперативная память и кэш *
|
||||
|
||||
|
||||
|
||||
@@ -1338,7 +1338,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
4.4 Память и кеш *
|
||||
4.4 Оперативная память и кэш *
|
||||
|
||||
|
||||
|
||||
@@ -1674,7 +1674,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
Глава 6. Хеширование
|
||||
Глава 6. Хеш-таблицы
|
||||
|
||||
|
||||
|
||||
@@ -1696,7 +1696,7 @@
|
||||
<span class="md-nav__icon md-icon"></span>
|
||||
|
||||
|
||||
Глава 6. Хеширование
|
||||
Глава 6. Хеш-таблицы
|
||||
|
||||
|
||||
</label>
|
||||
@@ -1774,7 +1774,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
6.3 Хеш-алгоритмы
|
||||
6.3 Алгоритмы хеширования
|
||||
|
||||
|
||||
|
||||
@@ -1869,7 +1869,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
Глава 7. Дерево
|
||||
Глава 7. Деревья
|
||||
|
||||
|
||||
|
||||
@@ -1891,7 +1891,7 @@
|
||||
<span class="md-nav__icon md-icon"></span>
|
||||
|
||||
|
||||
Глава 7. Дерево
|
||||
Глава 7. Деревья
|
||||
|
||||
|
||||
</label>
|
||||
@@ -1969,7 +1969,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
7.3 Представление дерева массивом
|
||||
7.3 Представление двоичного дерева массивом
|
||||
|
||||
|
||||
|
||||
@@ -2053,7 +2053,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
7.6 Резюме
|
||||
7.6 Краткие итоги
|
||||
|
||||
|
||||
|
||||
@@ -2216,7 +2216,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
8.3 Задача Top-K
|
||||
8.3 Задача Top-k
|
||||
|
||||
|
||||
|
||||
@@ -2307,7 +2307,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
Глава 9. Граф
|
||||
Глава 9. Графы
|
||||
|
||||
|
||||
|
||||
@@ -2329,7 +2329,7 @@
|
||||
<span class="md-nav__icon md-icon"></span>
|
||||
|
||||
|
||||
Глава 9. Граф
|
||||
Глава 9. Графы
|
||||
|
||||
|
||||
</label>
|
||||
@@ -2379,7 +2379,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
9.2 Базовые операции над графами
|
||||
9.2 Базовые операции графа
|
||||
|
||||
|
||||
|
||||
@@ -2435,7 +2435,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
9.4 Резюме
|
||||
9.4 Краткие итоги
|
||||
|
||||
|
||||
|
||||
@@ -2574,7 +2574,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.2 Точка вставки двоичного поиска
|
||||
10.2 Двоичный поиск точки вставки
|
||||
|
||||
|
||||
|
||||
@@ -2602,7 +2602,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.3 Граничные случаи двоичного поиска
|
||||
10.3 Двоичный поиск границ
|
||||
|
||||
|
||||
|
||||
@@ -2630,7 +2630,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.4 Стратегия оптимизации через хеширование
|
||||
10.4 Стратегии оптимизации хеширования
|
||||
|
||||
|
||||
|
||||
@@ -2658,7 +2658,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.5 Алгоритмы поиска: новый взгляд
|
||||
10.5 Переосмысление алгоритмов поиска
|
||||
|
||||
|
||||
|
||||
@@ -2863,7 +2863,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
11.3 Пузырьковая сортировка
|
||||
11.3 Сортировка пузырьком
|
||||
|
||||
|
||||
|
||||
@@ -2891,7 +2891,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
11.4 Сортировка вставкой
|
||||
11.4 Сортировка вставками
|
||||
|
||||
|
||||
|
||||
@@ -3196,7 +3196,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
12.1 Алгоритмы разделяй и властвуй
|
||||
12.1 Стратегия разделяй и властвуй
|
||||
|
||||
|
||||
|
||||
@@ -3224,7 +3224,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
12.2 Стратегия поиска разделяй и властвуй
|
||||
12.2 Поисковая стратегия разделяй и властвуй
|
||||
|
||||
|
||||
|
||||
@@ -3501,7 +3501,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
13.4 Задача о $n$ ферзях
|
||||
13.4 Задача о n ферзях
|
||||
|
||||
|
||||
|
||||
@@ -3642,7 +3642,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
14.1 Введение в динамическое программирование
|
||||
14.1 Первое знакомство с динамическим программированием
|
||||
|
||||
|
||||
|
||||
@@ -3754,7 +3754,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
14.5 Задача о неограниченном рюкзаке
|
||||
14.5 Задача о полном рюкзаке
|
||||
|
||||
|
||||
|
||||
@@ -4377,10 +4377,10 @@
|
||||
|
||||
<!-- Page content -->
|
||||
<h1 id="44">4.4 Оперативная память и кэш *<a class="headerlink" href="#44" title="Permanent link">¶</a></h1>
|
||||
<p>В первых двух разделах этой главы мы разобрали массивы и связные списки - две фундаментальные и важные структуры данных, которые соответственно представляют две физические структуры хранения: "непрерывное хранение" и "разрозненное хранение".</p>
|
||||
<p>На практике <strong>физическая структура во многом определяет, насколько эффективно программа использует память и кэш</strong>, а это, в свою очередь, влияет на общую производительность алгоритмической программы.</p>
|
||||
<p>В первых двух разделах этой главы мы разобрали массивы и связные списки - две базовые и важные структуры данных, которые представляют соответственно непрерывное хранение и разрозненное хранение.</p>
|
||||
<p>На практике <strong>физическая структура во многом определяет, насколько эффективно программа использует память и кэш</strong>, а это, в свою очередь, влияет на общую производительность алгоритма.</p>
|
||||
<h2 id="441">4.4.1 Устройства хранения данных в компьютере<a class="headerlink" href="#441" title="Permanent link">¶</a></h2>
|
||||
<p>В компьютере есть три типа устройств хранения данных: <u>жесткий диск (hard disk)</u> , <u>оперативная память (random-access memory, RAM)</u> и <u>кэш-память (cache memory)</u> . В таблице 4-2 показаны их различные роли и характеристики производительности в компьютерной системе.</p>
|
||||
<p>В компьютере есть три типа устройств хранения данных: <u>жесткий диск (hard disk)</u> , <u>оперативная память (random-access memory, RAM)</u> и <u>кэш-память (cache memory)</u> . В таблице 4-2 показаны их различные роли и характеристики в компьютерной системе.</p>
|
||||
<p align="center"> Таблица 4-2 Устройства хранения данных в компьютере </p>
|
||||
|
||||
<div class="center-table">
|
||||
@@ -4419,17 +4419,17 @@
|
||||
<td>Очень высокая, десятки и сотни GB/s</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Цена (юани)</td>
|
||||
<td>Дешевый, от долей юаня до нескольких юаней за GB</td>
|
||||
<td>Дорогая, десятки и сотни юаней за GB</td>
|
||||
<td>Очень дорогой, входит в стоимость упаковки CPU</td>
|
||||
<td>Цена</td>
|
||||
<td>Низкая, единицы валюты за GB</td>
|
||||
<td>Высокая, десятки и сотни валютных единиц за GB</td>
|
||||
<td>Очень высокая, входит в стоимость CPU</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<p>Компьютерную систему хранения можно представить в виде пирамиды, показанной на рисунке 4-9. Чем ближе устройство хранения к вершине пирамиды, тем оно быстрее, тем меньше его емкость и тем выше его стоимость. Такая многоуровневая конструкция возникла не случайно, а стала результатом тщательных инженерных компромиссов.</p>
|
||||
<ul>
|
||||
<li><strong>Жесткий диск трудно заменить оперативной памятью</strong>. Во-первых, данные в оперативной памяти исчезают после отключения питания, поэтому она не подходит для долговременного хранения. Во-вторых, память стоит в десятки раз дороже жесткого диска, что мешает ее широкому применению в потребительском сегменте.</li>
|
||||
<li><strong>Жесткий диск трудно заменить оперативной памятью</strong>. Во-первых, данные в оперативной памяти исчезают после отключения питания, поэтому она не подходит для долговременного хранения. Во-вторых, память стоит в разы дороже жесткого диска, что мешает ее широкому применению.</li>
|
||||
<li><strong>Кэш не может одновременно быть и очень большим, и очень быстрым</strong>. По мере роста емкости кэшей L1, L2 и L3 их физический размер увеличивается, расстояние до ядра CPU становится больше, время передачи данных растет, а задержка доступа к элементам увеличивается. При текущем уровне технологий многоуровневая структура кэша является лучшим балансом между емкостью, скоростью и стоимостью.</li>
|
||||
</ul>
|
||||
<p><img alt="Система хранения данных компьютера" class="animation-figure" src="../ram_and_cache.assets/storage_pyramid.png" /></p>
|
||||
@@ -4437,20 +4437,20 @@
|
||||
|
||||
<div class="admonition tip">
|
||||
<p class="admonition-title">Tip</p>
|
||||
<p>Иерархия памяти компьютера отражает тонкий баланс между скоростью, емкостью и стоимостью. На самом деле подобные компромиссы встречаются почти во всех отраслях инженерии: приходится искать оптимальный баланс между преимуществами и ограничениями.</p>
|
||||
<p>Иерархия памяти компьютера отражает тонкий баланс между скоростью, емкостью и стоимостью. Подобные компромиссы встречаются почти во всех областях инженерии: приходится искать оптимальный баланс между преимуществами и ограничениями.</p>
|
||||
</div>
|
||||
<p>В итоге <strong>жесткий диск используется для долговременного хранения больших объемов данных, оперативная память - для временного хранения данных, с которыми программа работает прямо сейчас, а кэш - для хранения часто используемых данных и инструкций</strong>, чтобы ускорять выполнение программ. Все три уровня работают совместно и обеспечивают эффективную работу компьютерной системы.</p>
|
||||
<p>Как показано на рисунке 4-10, во время выполнения программы данные читаются с жесткого диска в оперативную память, а затем используются CPU в вычислениях. Кэш можно рассматривать как часть CPU: <strong>он интеллектуально подгружает данные из оперативной памяти</strong>, обеспечивая CPU высокоскоростной доступ и тем самым значительно ускоряя выполнение программы и уменьшая зависимость от более медленной RAM.</p>
|
||||
<p>Как показано на рисунке 4-10, во время выполнения программы данные читаются с жесткого диска в оперативную память, а затем используются CPU в вычислениях. Кэш можно рассматривать как часть CPU: <strong>он подгружает данные из оперативной памяти</strong>, обеспечивая CPU высокоскоростной доступ и тем самым значительно ускоряя выполнение программы и уменьшая зависимость от более медленной RAM.</p>
|
||||
<p><img alt="Поток данных между жестким диском, RAM и кэшем" class="animation-figure" src="../ram_and_cache.assets/computer_storage_devices.png" /></p>
|
||||
<p align="center"> Рисунок 4-10 Поток данных между жестким диском, RAM и кэшем </p>
|
||||
|
||||
<h2 id="442">4.4.2 Эффективность использования памяти структурами данных<a class="headerlink" href="#442" title="Permanent link">¶</a></h2>
|
||||
<p>С точки зрения использования пространства памяти массивы и связные списки имеют свои преимущества и ограничения.</p>
|
||||
<p>С одной стороны, <strong>память ограничена, и один и тот же участок памяти не может совместно использоваться несколькими программами</strong>, поэтому нам хочется, чтобы структуры данных использовали пространство как можно эффективнее. Элементы массива расположены плотно и не требуют дополнительного места для хранения ссылок (указателей) между узлами списка, поэтому массивы эффективнее по памяти. Однако массиву нужно сразу выделить достаточно большой непрерывный участок памяти, что может приводить к потерям пространства, а его расширение требует дополнительных затрат времени и памяти. Напротив, связные списки выполняют динамическое выделение и освобождение памяти "по узлам", что дает большую гибкость.</p>
|
||||
<p>С одной стороны, <strong>память ограничена, и один и тот же участок памяти не может совместно использоваться несколькими программами</strong>, поэтому нам хочется, чтобы структуры данных использовали пространство как можно эффективнее. Элементы массива расположены плотно и не требуют дополнительного места для хранения ссылок (указателей) между узлами списка, поэтому массивы эффективнее по памяти. Однако массиву нужно сразу выделить достаточно большой непрерывный участок памяти, что может приводить к потерям пространства, а его расширение требует дополнительных затрат времени и памяти. Напротив, связные списки выделяют и освобождают память на уровне узлов, что дает большую гибкость.</p>
|
||||
<p>С другой стороны, во время выполнения программы <strong>при многократном выделении и освобождении памяти фрагментация свободной памяти становится все более серьезной</strong>, что снижает эффективность ее использования. Массивы из-за непрерывного хранения относительно менее подвержены фрагментации. Напротив, элементы связного списка распределены по памяти, и частые операции вставки и удаления легче приводят к фрагментации.</p>
|
||||
<h2 id="443">4.4.3 Эффективность использования кэша структурами данных<a class="headerlink" href="#443" title="Permanent link">¶</a></h2>
|
||||
<p>Хотя по объему кэш намного меньше оперативной памяти, он значительно быстрее и играет критически важную роль в скорости выполнения программ. Поскольку объем кэша ограничен и в нем можно хранить только небольшую долю часто используемых данных, когда CPU пытается обратиться к данным, которых в кэше нет, происходит <u>промах кэша (cache miss)</u> , и CPU вынужден загружать нужные данные из более медленной памяти.</p>
|
||||
<p>Очевидно, что <strong>чем меньше "промахов кэша", тем выше эффективность чтения и записи данных CPU</strong>, а значит, тем лучше производительность программы. Долю обращений, при которых CPU успешно получает данные из кэша, называют <u>коэффициентом попадания в кэш (cache hit rate)</u> ; этот показатель обычно используют для оценки эффективности кэша.</p>
|
||||
<p>Очевидно, что <strong>чем меньше промахов кэша, тем выше эффективность чтения и записи данных CPU</strong>, а значит, тем лучше производительность программы. Долю обращений, при которых CPU успешно получает данные из кэша, называют <u>коэффициентом попадания в кэш (cache hit rate)</u> ; этот показатель обычно используют для оценки эффективности кэша.</p>
|
||||
<p>Чтобы добиться как можно большей эффективности, кэш использует следующие механизмы загрузки данных.</p>
|
||||
<ul>
|
||||
<li><strong>Строки кэша</strong>: кэш хранит и загружает данные не по одному байту, а строками кэша. По сравнению с передачей по байтам это гораздо эффективнее.</li>
|
||||
@@ -4461,8 +4461,8 @@
|
||||
<p>На практике <strong>массивы и связные списки по-разному используют кэш</strong>, и это проявляется в нескольких аспектах.</p>
|
||||
<ul>
|
||||
<li><strong>Занимаемое пространство</strong>: элементы связного списка занимают больше места, чем элементы массива, поэтому в кэше помещается меньше полезных данных.</li>
|
||||
<li><strong>Строки кэша</strong>: данные списка разбросаны по памяти, а кэш загружает данные "строками", поэтому доля бесполезно загружаемых данных оказывается выше.</li>
|
||||
<li><strong>Механизм предвыборки</strong>: шаблон доступа к данным у массивов более "предсказуем", чем у списков, то есть системе легче угадать, какие данные понадобятся следующими.</li>
|
||||
<li><strong>Строки кэша</strong>: данные списка разбросаны по памяти, а кэш загружает данные строками, поэтому доля бесполезно загружаемых данных оказывается выше.</li>
|
||||
<li><strong>Механизм предвыборки</strong>: шаблон доступа к данным у массивов более предсказуем, чем у списков, то есть системе легче угадать, какие данные понадобятся следующими.</li>
|
||||
<li><strong>Пространственная локальность</strong>: массив хранится в компактной области памяти, поэтому данные рядом с уже загруженными с большей вероятностью скоро будут использованы.</li>
|
||||
</ul>
|
||||
<p>В целом <strong>массивы имеют более высокий коэффициент попадания в кэш, поэтому по эффективности операций они обычно превосходят связные списки</strong>. Именно поэтому при решении алгоритмических задач структуры данных на основе массивов часто оказываются предпочтительнее.</p>
|
||||
|
||||
@@ -65,8 +65,8 @@
|
||||
|
||||
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Noto+Sans:300,300i,400,400i,500,500i,700,700i%7CJetBrains+Mono:400,400i,700,700i&display=fallback">
|
||||
<style>:root{--md-text-font:"Noto Sans";--md-code-font:"JetBrains Mono"}</style>
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=PT+Sans:300,300i,400,400i,500,500i,700,700i%7CJetBrains+Mono:400,400i,700,700i&display=fallback">
|
||||
<style>:root{--md-text-font:"PT Sans";--md-code-font:"JetBrains Mono"}</style>
|
||||
|
||||
|
||||
|
||||
@@ -574,7 +574,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
Глава 1. Знакомство с алгоритмами
|
||||
Глава 1. Введение в алгоритмы
|
||||
|
||||
|
||||
|
||||
@@ -596,7 +596,7 @@
|
||||
<span class="md-nav__icon md-icon"></span>
|
||||
|
||||
|
||||
Глава 1. Знакомство с алгоритмами
|
||||
Глава 1. Введение в алгоритмы
|
||||
|
||||
|
||||
</label>
|
||||
@@ -646,7 +646,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
1.2 Что такое структуры данных и алгоритмы
|
||||
1.2 Что такое алгоритм
|
||||
|
||||
|
||||
|
||||
@@ -1183,7 +1183,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
Глава 4. Массив и связный список
|
||||
Глава 4. Массивы и списки
|
||||
|
||||
|
||||
|
||||
@@ -1205,7 +1205,7 @@
|
||||
<span class="md-nav__icon md-icon"></span>
|
||||
|
||||
|
||||
Глава 4. Массив и связный список
|
||||
Глава 4. Массивы и списки
|
||||
|
||||
|
||||
</label>
|
||||
@@ -1311,7 +1311,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
4.4 Память и кеш *
|
||||
4.4 Оперативная память и кэш *
|
||||
|
||||
|
||||
|
||||
@@ -1663,7 +1663,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
Глава 6. Хеширование
|
||||
Глава 6. Хеш-таблицы
|
||||
|
||||
|
||||
|
||||
@@ -1685,7 +1685,7 @@
|
||||
<span class="md-nav__icon md-icon"></span>
|
||||
|
||||
|
||||
Глава 6. Хеширование
|
||||
Глава 6. Хеш-таблицы
|
||||
|
||||
|
||||
</label>
|
||||
@@ -1763,7 +1763,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
6.3 Хеш-алгоритмы
|
||||
6.3 Алгоритмы хеширования
|
||||
|
||||
|
||||
|
||||
@@ -1858,7 +1858,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
Глава 7. Дерево
|
||||
Глава 7. Деревья
|
||||
|
||||
|
||||
|
||||
@@ -1880,7 +1880,7 @@
|
||||
<span class="md-nav__icon md-icon"></span>
|
||||
|
||||
|
||||
Глава 7. Дерево
|
||||
Глава 7. Деревья
|
||||
|
||||
|
||||
</label>
|
||||
@@ -1958,7 +1958,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
7.3 Представление дерева массивом
|
||||
7.3 Представление двоичного дерева массивом
|
||||
|
||||
|
||||
|
||||
@@ -2042,7 +2042,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
7.6 Резюме
|
||||
7.6 Краткие итоги
|
||||
|
||||
|
||||
|
||||
@@ -2205,7 +2205,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
8.3 Задача Top-K
|
||||
8.3 Задача Top-k
|
||||
|
||||
|
||||
|
||||
@@ -2296,7 +2296,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
Глава 9. Граф
|
||||
Глава 9. Графы
|
||||
|
||||
|
||||
|
||||
@@ -2318,7 +2318,7 @@
|
||||
<span class="md-nav__icon md-icon"></span>
|
||||
|
||||
|
||||
Глава 9. Граф
|
||||
Глава 9. Графы
|
||||
|
||||
|
||||
</label>
|
||||
@@ -2368,7 +2368,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
9.2 Базовые операции над графами
|
||||
9.2 Базовые операции графа
|
||||
|
||||
|
||||
|
||||
@@ -2424,7 +2424,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
9.4 Резюме
|
||||
9.4 Краткие итоги
|
||||
|
||||
|
||||
|
||||
@@ -2563,7 +2563,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.2 Точка вставки двоичного поиска
|
||||
10.2 Двоичный поиск точки вставки
|
||||
|
||||
|
||||
|
||||
@@ -2591,7 +2591,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.3 Граничные случаи двоичного поиска
|
||||
10.3 Двоичный поиск границ
|
||||
|
||||
|
||||
|
||||
@@ -2619,7 +2619,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.4 Стратегия оптимизации через хеширование
|
||||
10.4 Стратегии оптимизации хеширования
|
||||
|
||||
|
||||
|
||||
@@ -2647,7 +2647,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.5 Алгоритмы поиска: новый взгляд
|
||||
10.5 Переосмысление алгоритмов поиска
|
||||
|
||||
|
||||
|
||||
@@ -2852,7 +2852,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
11.3 Пузырьковая сортировка
|
||||
11.3 Сортировка пузырьком
|
||||
|
||||
|
||||
|
||||
@@ -2880,7 +2880,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
11.4 Сортировка вставкой
|
||||
11.4 Сортировка вставками
|
||||
|
||||
|
||||
|
||||
@@ -3185,7 +3185,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
12.1 Алгоритмы разделяй и властвуй
|
||||
12.1 Стратегия разделяй и властвуй
|
||||
|
||||
|
||||
|
||||
@@ -3213,7 +3213,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
12.2 Стратегия поиска разделяй и властвуй
|
||||
12.2 Поисковая стратегия разделяй и властвуй
|
||||
|
||||
|
||||
|
||||
@@ -3490,7 +3490,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
13.4 Задача о $n$ ферзях
|
||||
13.4 Задача о n ферзях
|
||||
|
||||
|
||||
|
||||
@@ -3631,7 +3631,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
14.1 Введение в динамическое программирование
|
||||
14.1 Первое знакомство с динамическим программированием
|
||||
|
||||
|
||||
|
||||
@@ -3743,7 +3743,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
14.5 Задача о неограниченном рюкзаке
|
||||
14.5 Задача о полном рюкзаке
|
||||
|
||||
|
||||
|
||||
@@ -4357,11 +4357,11 @@
|
||||
<h1 id="45">4.5 Резюме<a class="headerlink" href="#45" title="Permanent link">¶</a></h1>
|
||||
<h3 id="1">1. Ключевые выводы<a class="headerlink" href="#1" title="Permanent link">¶</a></h3>
|
||||
<ul>
|
||||
<li>Массивы и связные списки - это две базовые структуры данных, представляющие два способа хранения данных в памяти компьютера: хранение в непрерывной области и хранение в разрозненных областях. Их свойства во многом взаимно дополняют друг друга.</li>
|
||||
<li>Массив поддерживает произвольный доступ и занимает меньше памяти; однако вставка и удаление элементов в нем неэффективны, а длина после инициализации неизменяема.</li>
|
||||
<li>Связный список позволяет эффективно вставлять и удалять узлы путем изменения ссылок (указателей), а также гибко менять длину; однако доступ к узлам неэффективен, а памяти он занимает больше. Распространенные типы списков включают односвязные, циклические и двусвязные списки.</li>
|
||||
<li>Массивы и связные списки - это две базовые структуры данных, представляющие два способа хранения данных в памяти компьютера: хранение в непрерывном пространстве и хранение в разрозненном пространстве. Их свойства во многом взаимно дополняют друг друга.</li>
|
||||
<li>Массив поддерживает произвольный доступ и занимает меньше памяти; однако вставка и удаление элементов в нем неэффективны, а длина после инициализации фиксирована.</li>
|
||||
<li>Связный список позволяет эффективно вставлять и удалять узлы путем изменения ссылок (указателей), а также гибко менять длину; однако доступ к узлам менее эффективен, а памяти он занимает больше. Распространенные типы списков включают односвязные, циклические и двусвязные списки.</li>
|
||||
<li>Список - это упорядоченная коллекция элементов, поддерживающая добавление, удаление, поиск и изменение, и обычно реализуемая на основе динамического массива. Он сохраняет преимущества массива и при этом может гибко менять длину.</li>
|
||||
<li>Появление списка значительно повысило практическую полезность массива, хотя это и может приводить к потерям части памяти.</li>
|
||||
<li>Появление списка значительно повысило практическую ценность массива, хотя это и может приводить к потере части памяти.</li>
|
||||
<li>Во время работы программы данные в основном хранятся в оперативной памяти. Массив обеспечивает более высокую эффективность использования пространства памяти, а связный список дает большую гибкость в использовании памяти.</li>
|
||||
<li>Кэш, используя строки кэша, механизм предвыборки, а также пространственную и временную локальность, предоставляет CPU быстрый доступ к данным и заметно повышает эффективность выполнения программ.</li>
|
||||
<li>Поскольку массивы обычно имеют более высокий коэффициент попадания в кэш, они в большинстве случаев работают эффективнее списков. При выборе структуры данных нужно исходить из конкретных требований и сценариев.</li>
|
||||
@@ -4433,7 +4433,7 @@ aria-label="Нижний колонтитул"
|
||||
<a
|
||||
href="../ram_and_cache/"
|
||||
class="md-footer__link md-footer__link--prev"
|
||||
aria-label="Назад: 4.4 Память и кеш *"
|
||||
aria-label="Назад: 4.4 Оперативная память и кэш *"
|
||||
rel="prev"
|
||||
>
|
||||
<div class="md-footer__button md-icon">
|
||||
@@ -4445,7 +4445,7 @@ aria-label="Нижний колонтитул"
|
||||
Назад
|
||||
</span>
|
||||
<div class="md-ellipsis">
|
||||
4.4 Память и кеш *
|
||||
4.4 Оперативная память и кэш *
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
Reference in New Issue
Block a user