Что выведет код?
#Tasks
import java.util.*;
public class Task190126 {
public static void main(String[] args) {
List<Integer> list = Arrays.asList(5, 2, 9, 1, 5, 6);
Comparator<Integer> comparator = (a, b) -> {
if (a % 2 == b % 2) return 0;
return a % 2 == 0 ? -1 : 1;
};
Collections.sort(list, comparator);
System.out.println(list);
}
}
#Tasks
👍3
Варианты ответа:
Anonymous Quiz
28%
[2, 6, 5, 9, 1, 5]
28%
[5, 2, 9, 1, 5, 6]
22%
[1, 2, 5, 5, 6, 9]
22%
Исключение IllegalArgumentException
🤯3
Что такое idempotency и зачем она нужна? 🤓
Ответ:
Идемпотентная операция даёт одинаковый результат при повторном выполнении.
Это критично для REST, retries и distributed systems.
Например, повторный POST без идемпотентности может создать дубликаты.
#собеседование
Ответ:
Это критично для REST, retries и distributed systems.
Например, повторный POST без идемпотентности может создать дубликаты.
#собеседование
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
История IT-технологий сегодня — 20 января
ℹ️ Кто родился в этот день
Уильям Ральф Райт (англ. William Ralph Wright, род. 20 января 1960 года, Атланта, Джорджия, США) — американский разработчик и дизайнер компьютерных игр, основатель компании по разработке игр Maxis, а позднее — и компании Syntertainment. Получил наибольшую известность как первоначальный дизайнер популярных компьютерных игр SimCity, The Sims и Spore. Был удостоен премии BAFTA.
Андре́-Мари́ Ампе́р (фр. André-Marie Ampère; 20 января 1775 — 10 июня 1836) — французский физик, математик и естествоиспытатель. Джеймс Максвелл назвал Ампера «Ньютоном электричества». Ампер создал первую теорию, которая выражала связь электрических и магнитных явлений, ввёл в физику понятие электрического тока и проницательно предположил, что магнетизм вызван электрическими токами «на молекулярном уровне». Внёс значительный вклад в механику, теорию вероятностей, математический анализ.
Кэндзиро Такаянаги (яп. 高柳 健次郎 Такаянаги Кэндзиро:, 20 января 1899, Хамамацу — 23 июля 1990, Йокосука) — японский конструктор, создатель первого в мире полностью электронного телеприёмника. Увлёкся телевидением в 1925 году после прочтения во французском журнале статьи о новой технологии. Уже в 1926 году доктор Такаянаги впервые в мире при помощи электронно-лучевой трубки продемонстрировал изображение каны イ. После Второй мировой войны Такаянаги пришёл в компанию JVC, где занимал должность вице-президента.
А еще наш один из самых первых подписчиков - @RumEvo. С днем рождения🎉
🌐 Знаковые события
1960 — осуществлён первый пуск межконтинентальной баллистической ракеты Р-7А на предельную дальность в район Тихого океана. Принятие ракеты на вооружение.
#Biography #Birth_Date #Events #20Января
Уильям Ральф Райт (англ. William Ralph Wright, род. 20 января 1960 года, Атланта, Джорджия, США) — американский разработчик и дизайнер компьютерных игр, основатель компании по разработке игр Maxis, а позднее — и компании Syntertainment. Получил наибольшую известность как первоначальный дизайнер популярных компьютерных игр SimCity, The Sims и Spore. Был удостоен премии BAFTA.
Андре́-Мари́ Ампе́р (фр. André-Marie Ampère; 20 января 1775 — 10 июня 1836) — французский физик, математик и естествоиспытатель. Джеймс Максвелл назвал Ампера «Ньютоном электричества». Ампер создал первую теорию, которая выражала связь электрических и магнитных явлений, ввёл в физику понятие электрического тока и проницательно предположил, что магнетизм вызван электрическими токами «на молекулярном уровне». Внёс значительный вклад в механику, теорию вероятностей, математический анализ.
Кэндзиро Такаянаги (яп. 高柳 健次郎 Такаянаги Кэндзиро:, 20 января 1899, Хамамацу — 23 июля 1990, Йокосука) — японский конструктор, создатель первого в мире полностью электронного телеприёмника. Увлёкся телевидением в 1925 году после прочтения во французском журнале статьи о новой технологии. Уже в 1926 году доктор Такаянаги впервые в мире при помощи электронно-лучевой трубки продемонстрировал изображение каны イ. После Второй мировой войны Такаянаги пришёл в компанию JVC, где занимал должность вице-президента.
А еще наш один из самых первых подписчиков - @RumEvo. С днем рождения
1960 — осуществлён первый пуск межконтинентальной баллистической ракеты Р-7А на предельную дальность в район Тихого океана. Принятие ракеты на вооружение.
#Biography #Birth_Date #Events #20Января
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2🍾1
Как вы считаете, стоит ли мне настроить выпуск свежих видео и статей сначала на чем-то типа boosty, чтобы заработать шекелей, а потом и везде, или я просто охуел от наглости и таких мыслей?
Anonymous Poll
28%
Да ты охуел!
52%
Не, а что правильно, за труд можно и попросить плату.
20%
Мне похер, я не понимаю, что я тут делаю
🔥1👾1
Раздел 7. Алгоритмы
Глава 3: Алгоритмы сортировки и подготовка данных
Квадратичные сортировки: фундамент понимания
Классические алгоритмы O(n²)
Квадратичные сортировки представляют собой интеллектуальную основу для понимания более сложных алгоритмов. Их простота позволяет ясно увидеть фундаментальные принципы упорядочивания данных.
Пузырьковая сортировка (Bubble Sort)
Принцип работы: алгоритм последовательно сравнивает соседние элементы и меняет их местами, если они находятся в неправильном порядке. За каждый проход наибольший "всплывающий" элемент занимает свою окончательную позицию.
Характеристики:
Временная сложность: O(n²) в худшем и среднем случае
Пространственная сложность: O(1) (in-place)
Устойчивость: да (не меняет порядок равных элементов)
Особенность: после k итераций последние k элементов находятся на своих местах
Оптимизация: добавление флага прекращает выполнение, если на проходе не было обменов. Для уже отсортированного массива это дает O(n).
Сортировка выбором (Selection Sort)
Принцип работы: алгоритм делит массив на отсортированную и неотсортированную части. На каждом шаге он находит минимальный элемент в неотсортированной части и перемещает его в конец отсортированной.
Характеристики:
Временная сложность: всегда O(n²) независимо от исходных данных
Количество сравнений: n(n-1)/2
Количество обменов: n-1 (минимальное среди квадратичных алгоритмов)
Устойчивость: нет (может менять порядок равных элементов)
Преимущество: минимальное количество операций записи, что важно для устройств с ограниченным ресурсом записи (например, флеш-память)
Сортировка вставками (Insertion Sort)
Принцип работы: алгоритм строит отсортированную последовательность постепенно, вставляя каждый новый элемент в правильную позицию относительно уже отсортированной части.
Характеристики:
Временная сложность: O(n²) в худшем случае, O(n) в лучшем (уже отсортированный массив)
Количество сравнений: от n-1 до n(n-1)/2
Количество обменов: от 0 до n(n-1)/2
Устойчивость: да
Особенность: эффективен на небольших наборах данных (n < 50) и почти отсортированных массивах
Адаптивность сортировки вставками
Эффективность на почти отсортированных данных
Сортировка вставками обладает свойством адаптивности: ее время выполнения зависит от степени упорядоченности входных данных. Для массива, в котором каждый элемент находится не более чем на k позиций от своего окончательного места, сложность составляет O(nk).
На практически отсортированных данных (k мало) алгоритм приближается к линейному времени.
#Java #для_новичков #beginner #algorithm #sorted
Глава 3: Алгоритмы сортировки и подготовка данных
Квадратичные сортировки: фундамент понимания
Классические алгоритмы O(n²)
Квадратичные сортировки представляют собой интеллектуальную основу для понимания более сложных алгоритмов. Их простота позволяет ясно увидеть фундаментальные принципы упорядочивания данных.
Пузырьковая сортировка (Bubble Sort)
Принцип работы: алгоритм последовательно сравнивает соседние элементы и меняет их местами, если они находятся в неправильном порядке. За каждый проход наибольший "всплывающий" элемент занимает свою окончательную позицию.
public class BubbleSort {
public static void sort(int[] arr) {
int n = arr.length;
for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
// Обмен элементов
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
}Характеристики:
Временная сложность: O(n²) в худшем и среднем случае
Пространственная сложность: O(1) (in-place)
Устойчивость: да (не меняет порядок равных элементов)
Особенность: после k итераций последние k элементов находятся на своих местах
Оптимизация: добавление флага прекращает выполнение, если на проходе не было обменов. Для уже отсортированного массива это дает O(n).
Сортировка выбором (Selection Sort)
Принцип работы: алгоритм делит массив на отсортированную и неотсортированную части. На каждом шаге он находит минимальный элемент в неотсортированной части и перемещает его в конец отсортированной.
public class SelectionSort {
public static void sort(int[] arr) {
int n = arr.length;
for (int i = 0; i < n - 1; i++) {
int minIdx = i;
for (int j = i + 1; j < n; j++) {
if (arr[j] < arr[minIdx]) {
minIdx = j;
}
}
// Обмен текущего элемента с минимальным
int temp = arr[minIdx];
arr[minIdx] = arr[i];
arr[i] = temp;
}
}
}Характеристики:
Временная сложность: всегда O(n²) независимо от исходных данных
Количество сравнений: n(n-1)/2
Количество обменов: n-1 (минимальное среди квадратичных алгоритмов)
Устойчивость: нет (может менять порядок равных элементов)
Преимущество: минимальное количество операций записи, что важно для устройств с ограниченным ресурсом записи (например, флеш-память)
Сортировка вставками (Insertion Sort)
Принцип работы: алгоритм строит отсортированную последовательность постепенно, вставляя каждый новый элемент в правильную позицию относительно уже отсортированной части.
public class InsertionSort {
public static void sort(int[] arr) {
int n = arr.length;
for (int i = 1; i < n; i++) {
int key = arr[i];
int j = i - 1;
// Сдвигаем элементы, большие key, вправо
while (j >= 0 && arr[j] > key) {
arr[j + 1] = arr[j];
j--;
}
arr[j + 1] = key;
}
}
}Характеристики:
Временная сложность: O(n²) в худшем случае, O(n) в лучшем (уже отсортированный массив)
Количество сравнений: от n-1 до n(n-1)/2
Количество обменов: от 0 до n(n-1)/2
Устойчивость: да
Особенность: эффективен на небольших наборах данных (n < 50) и почти отсортированных массивах
Адаптивность сортировки вставками
Эффективность на почти отсортированных данных
Сортировка вставками обладает свойством адаптивности: ее время выполнения зависит от степени упорядоченности входных данных. Для массива, в котором каждый элемент находится не более чем на k позиций от своего окончательного места, сложность составляет O(nk).
На практически отсортированных данных (k мало) алгоритм приближается к линейному времени.
#Java #для_новичков #beginner #algorithm #sorted
👍5
Это делает его идеальным для:
Досортировки результатов предыдущих частичных сортировок
Поддержания порядка в динамически изменяемых коллекциях
Обработки потоковых данных, где новые элементы добавляются к уже отсортированной последовательности
Механизм адаптации
Алгоритм эффективен благодаря двум свойствам:
Локальность: при вставке нового элемента перемещения происходят только в его окрестности
Инкрементальность: каждая итерация поддерживает частично отсортированное состояние
Для уже отсортированного массива внутренний цикл while никогда не выполняется, и алгоритм делает ровно n-1 сравнение.
Применение в современных гибридных алгоритмах
Timsort: промышленный стандарт
Timsort — гибридный алгоритм, используемый в Python, Java (для массивов объектов), Android и V8. Он сочетает сортировку вставками и слиянием, демонстрируя эволюцию простых алгоритмов в промышленные решения.
В Timsort сортировка вставками применяется для:
Создания минимальных упорядоченных сегментов (run)
Досортировки мелких подмассивов (обычно до 32-64 элементов)
Причины выбора сортировки вставками для мелких массивов
Низкие константы: У сортировки вставками небольшие накладные расходы по сравнению с рекурсивными алгоритмами
Кэш-дружественность: Последовательный доступ к памяти хорошо работает с кэшем процессора
Адаптивность: На почти отсортированных данных она работает быстрее теоретически более быстрых алгоритмов
Другие гибридные применения
Introsort: использует быструю сортировку, но переключается на пирамидальную при глубокой рекурсии, а для маленьких подмассивов — на сортировку вставками
Сортировка Шелла: использует идею сортировки вставками, но сравнивает элементы, отстоящие далеко друг от друга, постепенно уменьшая шаг
Педагогическая ценность квадратичных алгоритмов
Квадратичные сортировки служат идеальной точкой входа в изучение алгоритмов по нескольким причинам:
Наглядность: Принципы работы можно понять без сложной математики
Полнота: Охватывают основные стратегии: сравнение соседей (пузырьковая), поиск минимума (выбором), вставка в упорядоченную последовательность (вставками)
Естественность: Сортировка вставками соответствует тому, как люди обычно упорядочивают карты в руке
Нижняя планка эффективности
Эти алгоритмы устанавливают базовый уровень, от которого можно измерять прогресс. Понимание, почему O(n²) неприемлемо для больших n, мотивирует изучение более эффективных методов.
Для n=1000:
Квадратичная сортировка: ~1,000,000 операций
Эффективная сортировка (n log n): ~10,000 операций
Разница в 100 раз становится критичной при масштабировании
Развитие алгоритмического мышления
Анализ квадратичных алгоритмов учит важным навыкам:
Анализ сложности: Понимание вложенных циклов и их стоимости
Оптимизация: Как небольшие изменения (флаг в пузырьковой) влияют на производительность
Адаптивность: Почему одни алгоритмы лучше работают на определенных данных
#Java #для_новичков #beginner #algorithm #sorted
Досортировки результатов предыдущих частичных сортировок
Поддержания порядка в динамически изменяемых коллекциях
Обработки потоковых данных, где новые элементы добавляются к уже отсортированной последовательности
Механизм адаптации
Алгоритм эффективен благодаря двум свойствам:
Локальность: при вставке нового элемента перемещения происходят только в его окрестности
Инкрементальность: каждая итерация поддерживает частично отсортированное состояние
Для уже отсортированного массива внутренний цикл while никогда не выполняется, и алгоритм делает ровно n-1 сравнение.
Применение в современных гибридных алгоритмах
Timsort: промышленный стандарт
Timsort — гибридный алгоритм, используемый в Python, Java (для массивов объектов), Android и V8. Он сочетает сортировку вставками и слиянием, демонстрируя эволюцию простых алгоритмов в промышленные решения.
В Timsort сортировка вставками применяется для:
Создания минимальных упорядоченных сегментов (run)
Досортировки мелких подмассивов (обычно до 32-64 элементов)
// Упрощенная концепция Timsort
public class TimsortConcept {
private static final int RUN = 32;
public static void timsort(int[] arr) {
// 1. Разбиваем на маленькие сегменты
for (int i = 0; i < arr.length; i += RUN) {
insertionSort(arr, i, Math.min(i + RUN - 1, arr.length - 1));
}
// 2. Сливаем сегменты попарно
// ... (реализация слияния)
}
// Оптимизированная сортировка вставками для диапазона
private static void insertionSort(int[] arr, int left, int right) {
for (int i = left + 1; i <= right; i++) {
int key = arr[i];
int j = i - 1;
// Используем бинарный поиск для нахождения позиции
int pos = binarySearch(arr, key, left, j);
// Сдвигаем элементы
while (j >= pos) {
arr[j + 1] = arr[j];
j--;
}
arr[j + 1] = key;
}
}
}
Причины выбора сортировки вставками для мелких массивов
Низкие константы: У сортировки вставками небольшие накладные расходы по сравнению с рекурсивными алгоритмами
Кэш-дружественность: Последовательный доступ к памяти хорошо работает с кэшем процессора
Адаптивность: На почти отсортированных данных она работает быстрее теоретически более быстрых алгоритмов
Другие гибридные применения
Introsort: использует быструю сортировку, но переключается на пирамидальную при глубокой рекурсии, а для маленьких подмассивов — на сортировку вставками
Сортировка Шелла: использует идею сортировки вставками, но сравнивает элементы, отстоящие далеко друг от друга, постепенно уменьшая шаг
Педагогическая ценность квадратичных алгоритмов
Квадратичные сортировки служат идеальной точкой входа в изучение алгоритмов по нескольким причинам:
Наглядность: Принципы работы можно понять без сложной математики
Полнота: Охватывают основные стратегии: сравнение соседей (пузырьковая), поиск минимума (выбором), вставка в упорядоченную последовательность (вставками)
Естественность: Сортировка вставками соответствует тому, как люди обычно упорядочивают карты в руке
Нижняя планка эффективности
Эти алгоритмы устанавливают базовый уровень, от которого можно измерять прогресс. Понимание, почему O(n²) неприемлемо для больших n, мотивирует изучение более эффективных методов.
Для n=1000:
Квадратичная сортировка: ~1,000,000 операций
Эффективная сортировка (n log n): ~10,000 операций
Разница в 100 раз становится критичной при масштабировании
Развитие алгоритмического мышления
Анализ квадратичных алгоритмов учит важным навыкам:
Анализ сложности: Понимание вложенных циклов и их стоимости
Оптимизация: Как небольшие изменения (флаг в пузырьковой) влияют на производительность
Адаптивность: Почему одни алгоритмы лучше работают на определенных данных
#Java #для_новичков #beginner #algorithm #sorted
👍4
Что выведет код?
#Tasks
import java.util.Arrays;
import java.util.Comparator;
public class Task200126 {
public static void main(String[] args) {
Integer[] arr = {5, 2, 8, 1, 9};
Comparator<Integer> comp = (a, b) -> a % 2 - b % 2;
insertionSort200126(arr, comp);
System.out.println(Arrays.toString(arr));
}
static <T> void insertionSort200126(T[] arr, Comparator<T> comp) {
for (int i = 1; i < arr.length; i++) {
T key = arr[i];
int j = i - 1;
while (j >= 0 && comp.compare(arr[j], key) > 0) {
arr[j + 1] = arr[j];
j--;
}
arr[j + 1] = key;
}
}
}
#Tasks
👍3
Варианты ответа:
Anonymous Quiz
33%
[1, 2, 5, 8, 9]
42%
[2, 8, 5, 1, 9]
17%
[1, 5, 9, 2, 8]
8%
[9, 8, 5, 2, 1]
👍3
Почему логирование в catch без проброса исключения опасно? 🤓
Ответ:
Ошибка маскируется, система продолжает работать в неконсистентном состоянии.
Это усложняет диагностику и может привести к скрытым сбоям.
Либо обрабатываем ошибку полностью, либо пробрасываем дальше.
#собеседование
Ответ:
Это усложняет диагностику и может привести к скрытым сбоям.
Либо обрабатываем ошибку полностью, либо пробрасываем дальше.
#собеседование
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
История IT-технологий сегодня — 21 января
ℹ️ Кто родился в этот день
Ким Дотком (нем. Kim Dotcom, при рождении Шмиц, нем. Schmitz, Kimble или Kim Tim Jim Vestor; 21 января 1974, Киль, Германия) — немецко-финский предприниматель, бывший владелец крупнейшего файлообменника Megaupload, с января по сентябрь 2013 года — владелец нового файлообменника Mega. Был арестован 19 января 2012 года в Новой Зеландии по запросу ФБР, но 22 февраля отпущен под залог. Власти США инкриминировали предпринимателю вымогательство, отмывание денег и массовые нарушения авторских прав и добивались его экстрадиции в США (слушания по экстрадиции проходили в августе 2012 года, но не увенчались успехом). В феврале 2017 года Верховный суд Новой Зеландии санкционировал экстрадицию основателя сайта Megaupload Кима Доткома в США.
Пол Гарднер А́ллен (англ. Paul Gardner Allen, 21 января 1953, Сиэтл, Вашингтон, США — 15 октября 2018, Сиэтл) — американский предприниматель, соучредитель корпорации Microsoft, которую он вместе со своим школьным приятелем Биллом Гейтсом основал в 1975 году. Капитал Аллена в 2018 году составлял $20,3 млрд.
🌐 Знаковые события
2004 — на 18-й марсианский день (Sol 18), марсоход Spirit внезапно перестал передавать данные и начал непрерывно перезагружаться. Файловая система флэш-памяти марсохода переполнилась мелкими файлами, оставшимися от полета, и RAM не хватило для их индексации при загрузке. Инженеры с Земли смогли удаленно отладить систему на расстоянии 56 млн км, удалив лишние файлы. Этот кейс вошел в учебники по программированию космических аппаратов.
#Biography #Birth_Date #Events #21Января
Ким Дотком (нем. Kim Dotcom, при рождении Шмиц, нем. Schmitz, Kimble или Kim Tim Jim Vestor; 21 января 1974, Киль, Германия) — немецко-финский предприниматель, бывший владелец крупнейшего файлообменника Megaupload, с января по сентябрь 2013 года — владелец нового файлообменника Mega. Был арестован 19 января 2012 года в Новой Зеландии по запросу ФБР, но 22 февраля отпущен под залог. Власти США инкриминировали предпринимателю вымогательство, отмывание денег и массовые нарушения авторских прав и добивались его экстрадиции в США (слушания по экстрадиции проходили в августе 2012 года, но не увенчались успехом). В феврале 2017 года Верховный суд Новой Зеландии санкционировал экстрадицию основателя сайта Megaupload Кима Доткома в США.
Пол Гарднер А́ллен (англ. Paul Gardner Allen, 21 января 1953, Сиэтл, Вашингтон, США — 15 октября 2018, Сиэтл) — американский предприниматель, соучредитель корпорации Microsoft, которую он вместе со своим школьным приятелем Биллом Гейтсом основал в 1975 году. Капитал Аллена в 2018 году составлял $20,3 млрд.
2004 — на 18-й марсианский день (Sol 18), марсоход Spirit внезапно перестал передавать данные и начал непрерывно перезагружаться. Файловая система флэш-памяти марсохода переполнилась мелкими файлами, оставшимися от полета, и RAM не хватило для их индексации при загрузке. Инженеры с Земли смогли удаленно отладить систему на расстоянии 56 млн км, удалив лишние файлы. Этот кейс вошел в учебники по программированию космических аппаратов.
#Biography #Birth_Date #Events #21Января
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3 2🔥1
Раздел 7. Алгоритмы
Глава 3: Алгоритмы сортировки и подготовка данных
Эффективные сортировки O(n log n): парадигмы и компромиссы
Парадигма «Разделяй и властвуй»
Алгоритмическая парадигма «Разделяй и властвуй» (Divide and Conquer) основана на рекурсивном разбиении задачи на подзадачи меньшего размера, решении этих подзадач и комбинировании результатов.
Три ключевых этапа:
Разделение: Разбиение исходной задачи на меньшие независимые подзадачи
Покорение: Рекурсивное решение подзадач
Объединение: Комбинирование результатов подзадач в решение исходной задачи
Эта парадигма лежит в основе большинства эффективных алгоритмов сортировки, демонстрируя, как рекурсивный подход может превращать квадратичные задачи в логарифмические.
Быстрая сортировка (QuickSort): скорость с оговорками
QuickSort выбирает опорный элемент (pivot) и разделяет массив на три части: элементы меньше pivot, равные pivot, и больше pivot. Затем рекурсивно сортирует части до и после pivot.
Критические особенности
Неустойчивость: Меняет относительный порядок равных элементов
Зависимость от выбора pivot: Качество разделения определяет эффективность
Худший случай O(n²): При неудачном выборе pivot (уже отсортированный массив + выбор крайнего элемента)
Средний случай O(n log n): При случайных данных или хорошей стратегии выбора pivot
Стратегии выбора pivot
Случайный элемент: Устраняет худший случай для предсказуемых данных
Медиана трех: Выбор из первого, среднего и последнего элементов
Introsort: Переключение на HeapSort при глубокой рекурсии
Практическое применение
QuickSort доминирует в стандартных библиотеках благодаря:
Отличной средней производительности
Кэш-дружественности (последовательный доступ при partition)
Возможности оптимизаций (интроспективная сортировка)
#Java #для_новичков #beginner #algorithm #sorted #QuickSort
Глава 3: Алгоритмы сортировки и подготовка данных
Эффективные сортировки O(n log n): парадигмы и компромиссы
Парадигма «Разделяй и властвуй»
Алгоритмическая парадигма «Разделяй и властвуй» (Divide and Conquer) основана на рекурсивном разбиении задачи на подзадачи меньшего размера, решении этих подзадач и комбинировании результатов.
Три ключевых этапа:
Разделение: Разбиение исходной задачи на меньшие независимые подзадачи
Покорение: Рекурсивное решение подзадач
Объединение: Комбинирование результатов подзадач в решение исходной задачи
Эта парадигма лежит в основе большинства эффективных алгоритмов сортировки, демонстрируя, как рекурсивный подход может превращать квадратичные задачи в логарифмические.
Быстрая сортировка (QuickSort): скорость с оговорками
QuickSort выбирает опорный элемент (pivot) и разделяет массив на три части: элементы меньше pivot, равные pivot, и больше pivot. Затем рекурсивно сортирует части до и после pivot.
public class QuickSort {
public static void sort(int[] arr) {
quickSort(arr, 0, arr.length - 1);
}
private static void quickSort(int[] arr, int low, int high) {
if (low < high) {
// Разделение массива
int pivotIndex = partition(arr, low, high);
// Рекурсивная сортировка двух частей
quickSort(arr, low, pivotIndex - 1);
quickSort(arr, pivotIndex + 1, high);
}
}
private static int partition(int[] arr, int low, int high) {
// Выбор опорного элемента (последний)
int pivot = arr[high];
int i = low - 1; // Индекс меньшего элемента
for (int j = low; j < high; j++) {
if (arr[j] <= pivot) {
i++;
swap(arr, i, j);
}
}
swap(arr, i + 1, high);
return i + 1;
}
}Критические особенности
Неустойчивость: Меняет относительный порядок равных элементов
Зависимость от выбора pivot: Качество разделения определяет эффективность
Худший случай O(n²): При неудачном выборе pivot (уже отсортированный массив + выбор крайнего элемента)
Средний случай O(n log n): При случайных данных или хорошей стратегии выбора pivot
Стратегии выбора pivot
Случайный элемент: Устраняет худший случай для предсказуемых данных
Медиана трех: Выбор из первого, среднего и последнего элементов
Introsort: Переключение на HeapSort при глубокой рекурсии
// Улучшенный выбор pivot
private static int medianOfThree(int[] arr, int low, int high) {
int mid = low + (high - low) / 2;
// Упорядочиваем три элемента
if (arr[low] > arr[mid]) swap(arr, low, mid);
if (arr[low] > arr[high]) swap(arr, low, high);
if (arr[mid] > arr[high]) swap(arr, mid, high);
return mid; // Медиана в середине
}
Практическое применение
QuickSort доминирует в стандартных библиотеках благодаря:
Отличной средней производительности
Кэш-дружественности (последовательный доступ при partition)
Возможности оптимизаций (интроспективная сортировка)
#Java #для_новичков #beginner #algorithm #sorted #QuickSort
👍5
Сортировка слиянием (MergeSort): стабильность и гарантии
MergeSort рекурсивно делит массив пополам до подмассивов размером 1, затем сливает упорядоченные подмассивы в большие упорядоченные массивы.
Ключевые характеристики
Устойчивость: Сохраняет относительный порядок равных элементов
Гарантированная сложность: Всегда O(n log n) независимо от входных данных
Дополнительная память O(n): Требует временного массива для слияния
Параллелизуемость: Легко распараллеливается благодаря независимости подзадач
Компромиссы
Память vs Стабильность: За стабильность и гарантии платим дополнительной памятью
Время vs Предсказуемость: Худший случай лучше, чем у QuickSort, но средний часто медленнее
Применение
Сортировка связанных списков (требует O(1) доп. памяти)
Внешняя сортировка больших файлов (слияние отсортированных блоков)
Там, где важна стабильность (многоуровневая сортировка)
#Java #для_новичков #beginner #algorithm #sorted #MergeSort
MergeSort рекурсивно делит массив пополам до подмассивов размером 1, затем сливает упорядоченные подмассивы в большие упорядоченные массивы.
public class MergeSort {
public static void sort(int[] arr) {
if (arr.length <= 1) return;
int mid = arr.length / 2;
int[] left = Arrays.copyOfRange(arr, 0, mid);
int[] right = Arrays.copyOfRange(arr, mid, arr.length);
sort(left);
sort(right);
merge(arr, left, right);
}
private static void merge(int[] result, int[] left, int[] right) {
int i = 0, j = 0, k = 0;
while (i < left.length && j < right.length) {
// Стабильность: сохраняем порядок равных элементов из левой части
if (left[i] <= right[j]) {
result[k++] = left[i++];
} else {
result[k++] = right[j++];
}
}
while (i < left.length) result[k++] = left[i++];
while (j < right.length) result[k++] = right[j++];
}
}Ключевые характеристики
Устойчивость: Сохраняет относительный порядок равных элементов
Гарантированная сложность: Всегда O(n log n) независимо от входных данных
Дополнительная память O(n): Требует временного массива для слияния
Параллелизуемость: Легко распараллеливается благодаря независимости подзадач
Компромиссы
Память vs Стабильность: За стабильность и гарантии платим дополнительной памятью
Время vs Предсказуемость: Худший случай лучше, чем у QuickSort, но средний часто медленнее
Применение
Сортировка связанных списков (требует O(1) доп. памяти)
Внешняя сортировка больших файлов (слияние отсортированных блоков)
Там, где важна стабильность (многоуровневая сортировка)
#Java #для_новичков #beginner #algorithm #sorted #MergeSort
👍5
Сортировка кучей (HeapSort): баланс памяти и производительности
Куча (heap) — двоичное дерево, удовлетворяющее свойству кучи: родитель всегда больше (max-heap) или меньше (min-heap) своих потомков.
Особенности HeapSort
Неустойчивость: Перестановки элементов нарушают исходный порядок
Дополнительная память O(1): Работает на месте (in-place)
Гарантированная сложность O(n log n): Худший случай не хуже
Кэш-недружественность: Случайный доступ к элементам при heapify
Применение в гибридных алгоритмах
HeapSort используется как защитный механизм:
Introsort: Быстрая сортировка + HeapSort при глубокой рекурсии
Heapsort для малых n: В некоторых реализациях для небольших массивов
Реализация приоритетных очередей: Структура кучи — основа PriorityQueue
Сравнительный анализ: три подхода к эффективности
По устойчивости
Устойчивые: MergeSort (сохраняет порядок равных)
Неустойчивые: QuickSort, HeapSort (меняют порядок)
По использованию памяти
O(1) дополнительной памяти: HeapSort (in-place)
O(log n) стековой памяти: QuickSort (рекурсия)
O(n) дополнительной памяти: MergeSort (временный массив)
По гарантиям времени
Всегда O(n log n): MergeSort, HeapSort
O(n²) в худшем, O(n log n) в среднем: QuickSort
По практической производительности
QuickSort: Самый быстрый в среднем случае, лучшая локальность кэша
HeapSort: Гарантии без доп. памяти, но медленнее из-за плохой локальности
MergeSort: Стабильность и параллелизуемость, но требует памяти
Применение парадигмы «Разделяй и властвуй»
Оба основных алгоритма следуют парадигме:
QuickSort:
Разделение: Partition по pivot (O(n))
Покорение: Рекурсивная сортировка двух частей
Объединение: Уже отсортировано на месте
MergeSort:
Разделение: Пополам (O(1))
Покорение: Рекурсивная сортировка половин
Объединение: Merge двух отсортированных массивов (O(n))
Анализ сложности
Рекуррентное соотношение для обоих алгоритмов (в среднем для QuickSort):
T(n) = 2T(n/2) + O(n)
По основной теореме о рекуррентных соотношениях это дает O(n log n).
Почему это эффективно
Разделение задачи размером n на две подзадачи размером n/2 уменьшает общий объем работы. Если бы разделение было линейным (например, на задачи размером n-1 и 1), сложность оставалась бы квадратичной.
#Java #для_новичков #beginner #algorithm #sorted #HeapSort
Куча (heap) — двоичное дерево, удовлетворяющее свойству кучи: родитель всегда больше (max-heap) или меньше (min-heap) своих потомков.
public class HeapSort {
public static void sort(int[] arr) {
int n = arr.length;
// Построение max-heap
for (int i = n / 2 - 1; i >= 0; i--) {
heapify(arr, n, i);
}
// Извлечение элементов из кучи
for (int i = n - 1; i > 0; i--) {
// Перемещаем корень (максимум) в конец
swap(arr, 0, i);
// Восстанавливаем кучу для уменьшенного массива
heapify(arr, i, 0);
}
}
private static void heapify(int[] arr, int n, int i) {
int largest = i; // Инициализируем корень как наибольший
int left = 2 * i + 1; // Левый потомок
int right = 2 * i + 2; // Правый потомок
// Если левый потомок больше корня
if (left < n && arr[left] > arr[largest]) {
largest = left;
}
// Если правый потомок больше текущего наибольшего
if (right < n && arr[right] > arr[largest]) {
largest = right;
}
// Если наибольший не корень
if (largest != i) {
swap(arr, i, largest);
heapify(arr, n, largest); // Рекурсивно heapify затронутое поддерево
}
}
}Особенности HeapSort
Неустойчивость: Перестановки элементов нарушают исходный порядок
Дополнительная память O(1): Работает на месте (in-place)
Гарантированная сложность O(n log n): Худший случай не хуже
Кэш-недружественность: Случайный доступ к элементам при heapify
Применение в гибридных алгоритмах
HeapSort используется как защитный механизм:
Introsort: Быстрая сортировка + HeapSort при глубокой рекурсии
Heapsort для малых n: В некоторых реализациях для небольших массивов
Реализация приоритетных очередей: Структура кучи — основа PriorityQueue
Сравнительный анализ: три подхода к эффективности
По устойчивости
Устойчивые: MergeSort (сохраняет порядок равных)
Неустойчивые: QuickSort, HeapSort (меняют порядок)
По использованию памяти
O(1) дополнительной памяти: HeapSort (in-place)
O(log n) стековой памяти: QuickSort (рекурсия)
O(n) дополнительной памяти: MergeSort (временный массив)
По гарантиям времени
Всегда O(n log n): MergeSort, HeapSort
O(n²) в худшем, O(n log n) в среднем: QuickSort
По практической производительности
QuickSort: Самый быстрый в среднем случае, лучшая локальность кэша
HeapSort: Гарантии без доп. памяти, но медленнее из-за плохой локальности
MergeSort: Стабильность и параллелизуемость, но требует памяти
Применение парадигмы «Разделяй и властвуй»
Оба основных алгоритма следуют парадигме:
QuickSort:
Разделение: Partition по pivot (O(n))
Покорение: Рекурсивная сортировка двух частей
Объединение: Уже отсортировано на месте
MergeSort:
Разделение: Пополам (O(1))
Покорение: Рекурсивная сортировка половин
Объединение: Merge двух отсортированных массивов (O(n))
Анализ сложности
Рекуррентное соотношение для обоих алгоритмов (в среднем для QuickSort):
T(n) = 2T(n/2) + O(n)
По основной теореме о рекуррентных соотношениях это дает O(n log n).
Почему это эффективно
Разделение задачи размером n на две подзадачи размером n/2 уменьшает общий объем работы. Если бы разделение было линейным (например, на задачи размером n-1 и 1), сложность оставалась бы квадратичной.
#Java #для_новичков #beginner #algorithm #sorted #HeapSort
👍5
Что выведет код?
#Tasks
import java.util.Arrays;
import java.util.Comparator;
public class Task210126 {
public static void main(String[] args) {
Integer[] arr = {3, 2, 8, 1, 6};
Comparator<Integer> comp = Comparator.comparingInt(i -> i % 2);
Arrays.sort(arr, comp);
System.out.println(Arrays.toString(arr));
}
}
#Tasks
👍3
Варианты ответа:
Anonymous Quiz
17%
[2, 6, 8, 1, 3]
59%
[2, 8, 6, 3, 1]
10%
[1, 3, 2, 6, 8]
14%
[3, 1, 2, 8, 6]
👍2
Чем отличается checked exception от бизнес-ошибки? 🤓
Ответ:
Checked — техническая ошибка среды выполнения.
Бизнес-ошибка — часть доменной логики и не должна использовать исключения JVM.
Обычно моделируется через Result, Either или специальные объекты состояния.
#собеседование
Ответ:
Бизнес-ошибка — часть доменной логики и не должна использовать исключения JVM.
Обычно моделируется через Result, Either или специальные объекты состояния.
#собеседование
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
История IT-технологий сегодня — 22 января
ℹ️ Кто родился в этот день
Фридьеш Рис (венг. Riesz Frigyes, в русскоязычных источниках часто пишется «Рисс»; 22 января 1880 — 28 февраля 1956) — выдающийся венгерский математик, один из основателей функционального анализа; пространство Риса и спектральная теория операторов лежат в основе современной теории сигналов, квантовой механики и многих алгоритмов обработки данных, используемых в IT.
🌐 Знаковые события
1992 — открыта первая экзопланета — PSR B1257+12 c.
#Biography #Birth_Date #Events #22Января
Фридьеш Рис (венг. Riesz Frigyes, в русскоязычных источниках часто пишется «Рисс»; 22 января 1880 — 28 февраля 1956) — выдающийся венгерский математик, один из основателей функционального анализа; пространство Риса и спектральная теория операторов лежат в основе современной теории сигналов, квантовой механики и многих алгоритмов обработки данных, используемых в IT.
1992 — открыта первая экзопланета — PSR B1257+12 c.
#Biography #Birth_Date #Events #22Января
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1🔥1
Раздел 7. Алгоритмы
Глава 3. Алгоритмы сортировки и подготовка данных
Практика : Реализовать сортировку выбором и сортировку слиянием для книг по году издания. Убедиться, что слияние сохраняет относительный порядок (устойчивость). Использовать Collections.sort() и исследовать, какой алгоритм применяется (Timsort — гибрид вставок и слияния).
Анализ: В каком случае для библиотечного приложения важна устойчивость сортировки? Когда можно пожертвовать памятью (MergeSort) ради гарантии, а когда важна экономия памяти (HeapSort)?
Мы реализуем две классические сортировки вручную:
Сортировка выбором (Selection Sort) — простой, понятный, но неэффективный алгоритм O(n²)
Сортировка слиянием (Merge Sort) — устойчивый алгоритм с гарантированной сложностью O(n log n) и дополнительной памятью O(n)
Подготовка к уроку
Перед началом убедитесь, что в проекте есть:
Класс Book с полями title, author, year (все поля должны иметь геттеры)
Класс Library с полем List<Book> books = new ArrayList<>()
Метод printAllBooks() или аналогичный для вывода списка книг с номерами
Рекомендуемые импорты в Library.java:
Javaimport java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
Шаг 1. Подготовка тестовых данных
Перед реализацией алгоритмов добавьте в main или в метод инициализации библиотеки набор книг с намеренными дубликатами годов и авторов, чтобы можно было проверить устойчивость сортировки.
Пример набора данных, который вы должны создать самостоятельно:
"1984", "Оруэлл", 1949
"Скотный двор", "Оруэлл", 1945
"Война и мир", "Толстой", 1869
"Анна Каренина", "Толстой", 1877
"Мастер и Маргарита", "Булгаков", 1967
"Собачье сердце", "Булгаков", 1925
"Преступление и наказание", "Достоевский", 1866
"Идиот", "Достоевский", 1869
"Братья Карамазовы", "Достоевский", 1880
Обратите внимание: два автора имеют одинаковый год (Оруэлл не имеет дублей, Достоевский имеет два произведения в 1869 году).
Шаг 2. Реализация сортировки выбором (Selection Sort) по году
Создайте в классе Library метод:public void selectionSortByYear()
Внутри метода:
Переберите массив/список внешним циклом от 0 до books.size()–2
Для каждого i найдите индекс минимального года в подмассиве [i … end]
Если найденный минимум не равен i — поменяйте местами элементы i и minIndex
После окончания внешнего цикла список должен быть отсортирован по году
После сортировки вызовите printAllBooks() — чтобы увидеть результат
Важные моменты для самостоятельной реализации:
Работайте с индексами (не создавайте новый список)
Сравнивайте book.getYear()
Обменяйте объекты целиком (не отдельные поля)
#Java #для_новичков #beginner #algorithm #sorted #HeapSort #Практика
Глава 3. Алгоритмы сортировки и подготовка данных
Практика : Реализовать сортировку выбором и сортировку слиянием для книг по году издания. Убедиться, что слияние сохраняет относительный порядок (устойчивость). Использовать Collections.sort() и исследовать, какой алгоритм применяется (Timsort — гибрид вставок и слияния).
Анализ: В каком случае для библиотечного приложения важна устойчивость сортировки? Когда можно пожертвовать памятью (MergeSort) ради гарантии, а когда важна экономия памяти (HeapSort)?
Мы реализуем две классические сортировки вручную:
Сортировка выбором (Selection Sort) — простой, понятный, но неэффективный алгоритм O(n²)
Сортировка слиянием (Merge Sort) — устойчивый алгоритм с гарантированной сложностью O(n log n) и дополнительной памятью O(n)
Подготовка к уроку
Перед началом убедитесь, что в проекте есть:
Класс Book с полями title, author, year (все поля должны иметь геттеры)
Класс Library с полем List<Book> books = new ArrayList<>()
Метод printAllBooks() или аналогичный для вывода списка книг с номерами
Рекомендуемые импорты в Library.java:
Javaimport java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
Шаг 1. Подготовка тестовых данных
Перед реализацией алгоритмов добавьте в main или в метод инициализации библиотеки набор книг с намеренными дубликатами годов и авторов, чтобы можно было проверить устойчивость сортировки.
Пример набора данных, который вы должны создать самостоятельно:
"1984", "Оруэлл", 1949
"Скотный двор", "Оруэлл", 1945
"Война и мир", "Толстой", 1869
"Анна Каренина", "Толстой", 1877
"Мастер и Маргарита", "Булгаков", 1967
"Собачье сердце", "Булгаков", 1925
"Преступление и наказание", "Достоевский", 1866
"Идиот", "Достоевский", 1869
"Братья Карамазовы", "Достоевский", 1880
Обратите внимание: два автора имеют одинаковый год (Оруэлл не имеет дублей, Достоевский имеет два произведения в 1869 году).
Шаг 2. Реализация сортировки выбором (Selection Sort) по году
Создайте в классе Library метод:public void selectionSortByYear()
Внутри метода:
Переберите массив/список внешним циклом от 0 до books.size()–2
Для каждого i найдите индекс минимального года в подмассиве [i … end]
Если найденный минимум не равен i — поменяйте местами элементы i и minIndex
После окончания внешнего цикла список должен быть отсортирован по году
После сортировки вызовите printAllBooks() — чтобы увидеть результат
Важные моменты для самостоятельной реализации:
Работайте с индексами (не создавайте новый список)
Сравнивайте book.getYear()
Обменяйте объекты целиком (не отдельные поля)
#Java #для_новичков #beginner #algorithm #sorted #HeapSort #Практика
👍1🔥1
Шаг 3. Реализация сортировки слиянием (Merge Sort) по году
Создайте метод: public void mergeSortByYear()
Реализуйте классический рекурсивный Merge Sort:
Создайте вспомогательный метод mergeSort(List<Book> list, int left, int right)
Если left < right:
mid = (left + right) / 2
Рекурсивно сортируйте левую половину
Рекурсивно сортируйте правую половину
Слейте две отсортированные половины в методе merge()
Реализуйте метод merge(List<Book> list, int left, int mid, int right):
Создайте временный список temp нужного размера
Два указателя i = left, j = mid+1
Пока обе половины не закончились — сравнивайте и копируйте меньший элемент
Докопируйте остаток левой или правой половины
Скопируйте temp обратно в исходный список на позиции left..right
Ключевой момент устойчивости:
Merge Sort устойчив — при равных ключах сохраняется относительный порядок исходных элементов.
После сортировки вызовите printAllBooks() и убедитесь, что книги Достоевского 1869 года остались в исходном порядке (Преступление → Идиот).
Шаг 4. Использование встроенной сортировки (Collections.sort и List.sort)
Создайте метод sortWithCollections():
Вызовите Collections.sort(books) — поскольку Book реализует Comparable по названию (из предыдущего урока), отсортирует по названию
Затем вызовите books.sort(Comparator.comparingInt(Book::getYear)) — сортировка по году
Затем вызовите books.sort(Comparator.comparing(Book::getAuthor).thenComparingInt(Book::getYear)) — по автору, затем по году
После каждой сортировки выводите список и наблюдайте порядок.
Исследование Timsort:
Начиная с Java 7, Collections.sort() и List.sort() используют Timsort — гибридный алгоритм:
Сортировка вставками для малых подмассивов (run ≤ 32)
Слияние (merge) для больших
Очень эффективен на реальных данных (частично отсортированных)
Устойчив — сохраняет относительный порядок равных элементов
Анализ: Когда важна устойчивость сортировки?
Устойчивость (stable sort) — когда при равных ключах сохраняется исходный относительный порядок элементов.
В библиотечном приложении устойчивость важна в следующих случаях:
Сортировка по году, но хочется сохранить алфавитный порядок авторов при одинаковом годе
→ Если два произведения Достоевского вышли в 1869 году — после сортировки по году они должны остаться в порядке появления в каталоге или по алфавиту названий.
Сортировка по рейтингу, но при равном рейтинге важен порядок добавления
→ Пользователь добавил книги в определённом порядке — при равном рейтинге хочется видеть их в этом же порядке.
Многоуровневая сортировка
→ Сначала по автору, затем по году — устойчивость гарантирует, что внутри одного автора книги останутся в порядке добавления или по названию.
Когда устойчивость не критична:
Сортировка по уникальному полю (ISBN, ID) — равных элементов нет
Когда порядок внутри группы не имеет значения (например, только по жанру)
Когда важна максимальная скорость и экономия памяти, а не порядок
Сравнение по памяти и устойчивости:
Прогноз при росте данных:
100 книг → любой алгоритм за миллисекунды
100 000 книг → Selection Sort — секунды, остальные — десятки миллисекунд
1 000 000 книг → Selection Sort — часы, Timsort/Merge — секунды, HeapSort — чуть быстрее MergeSort за счёт меньшей памяти
Вывод для библиотеки:
Основной выбор — List.sort() (Timsort): устойчивый, быстрый, адаптивный
Merge Sort вручную — только если нужно изучить алгоритм или требуется явный контроль
HeapSort — если память критична (очень редкий случай)
Selection Sort — исключительно для обучения
Практическое задание (объёмное)
Реализуйте selectionSortByYear() вручную.
Реализуйте рекурсивный mergeSortByYear() с вспомогательным merge.
Добавьте методы:
sortByTitleUsingCollections()
sortByAuthorThenYearUsingComparator()
sortByYearUsingLambda()
В main добавьте 10+ книг с дубликатами годов и авторов.
Выполните все сортировки подряд и выводите список после каждой.
Сравните порядок книг Достоевского 1869 года до и после сортировки по году — убедитесь в устойчивости Timsort и MergeSort.
#Java #для_новичков #beginner #algorithm #sorted #HeapSort #Практика
Создайте метод: public void mergeSortByYear()
Реализуйте классический рекурсивный Merge Sort:
Создайте вспомогательный метод mergeSort(List<Book> list, int left, int right)
Если left < right:
mid = (left + right) / 2
Рекурсивно сортируйте левую половину
Рекурсивно сортируйте правую половину
Слейте две отсортированные половины в методе merge()
Реализуйте метод merge(List<Book> list, int left, int mid, int right):
Создайте временный список temp нужного размера
Два указателя i = left, j = mid+1
Пока обе половины не закончились — сравнивайте и копируйте меньший элемент
Докопируйте остаток левой или правой половины
Скопируйте temp обратно в исходный список на позиции left..right
Ключевой момент устойчивости:
Merge Sort устойчив — при равных ключах сохраняется относительный порядок исходных элементов.
После сортировки вызовите printAllBooks() и убедитесь, что книги Достоевского 1869 года остались в исходном порядке (Преступление → Идиот).
Шаг 4. Использование встроенной сортировки (Collections.sort и List.sort)
Создайте метод sortWithCollections():
Вызовите Collections.sort(books) — поскольку Book реализует Comparable по названию (из предыдущего урока), отсортирует по названию
Затем вызовите books.sort(Comparator.comparingInt(Book::getYear)) — сортировка по году
Затем вызовите books.sort(Comparator.comparing(Book::getAuthor).thenComparingInt(Book::getYear)) — по автору, затем по году
После каждой сортировки выводите список и наблюдайте порядок.
Исследование Timsort:
Начиная с Java 7, Collections.sort() и List.sort() используют Timsort — гибридный алгоритм:
Сортировка вставками для малых подмассивов (run ≤ 32)
Слияние (merge) для больших
Очень эффективен на реальных данных (частично отсортированных)
Устойчив — сохраняет относительный порядок равных элементов
Анализ: Когда важна устойчивость сортировки?
Устойчивость (stable sort) — когда при равных ключах сохраняется исходный относительный порядок элементов.
В библиотечном приложении устойчивость важна в следующих случаях:
Сортировка по году, но хочется сохранить алфавитный порядок авторов при одинаковом годе
→ Если два произведения Достоевского вышли в 1869 году — после сортировки по году они должны остаться в порядке появления в каталоге или по алфавиту названий.
Сортировка по рейтингу, но при равном рейтинге важен порядок добавления
→ Пользователь добавил книги в определённом порядке — при равном рейтинге хочется видеть их в этом же порядке.
Многоуровневая сортировка
→ Сначала по автору, затем по году — устойчивость гарантирует, что внутри одного автора книги останутся в порядке добавления или по названию.
Когда устойчивость не критична:
Сортировка по уникальному полю (ISBN, ID) — равных элементов нет
Когда порядок внутри группы не имеет значения (например, только по жанру)
Когда важна максимальная скорость и экономия памяти, а не порядок
Сравнение по памяти и устойчивости:
Прогноз при росте данных:
100 книг → любой алгоритм за миллисекунды
100 000 книг → Selection Sort — секунды, остальные — десятки миллисекунд
1 000 000 книг → Selection Sort — часы, Timsort/Merge — секунды, HeapSort — чуть быстрее MergeSort за счёт меньшей памяти
Вывод для библиотеки:
Основной выбор — List.sort() (Timsort): устойчивый, быстрый, адаптивный
Merge Sort вручную — только если нужно изучить алгоритм или требуется явный контроль
HeapSort — если память критична (очень редкий случай)
Selection Sort — исключительно для обучения
Практическое задание (объёмное)
Реализуйте selectionSortByYear() вручную.
Реализуйте рекурсивный mergeSortByYear() с вспомогательным merge.
Добавьте методы:
sortByTitleUsingCollections()
sortByAuthorThenYearUsingComparator()
sortByYearUsingLambda()
В main добавьте 10+ книг с дубликатами годов и авторов.
Выполните все сортировки подряд и выводите список после каждой.
Сравните порядок книг Достоевского 1869 года до и после сортировки по году — убедитесь в устойчивости Timsort и MergeSort.
#Java #для_новичков #beginner #algorithm #sorted #HeapSort #Практика
👍1