Продолжаем рассказывать о разных видах алгоритмов сортировок. Мы уже разобрали самую простую пузырьковую сортировку и теперь улучшаем её — пишем сортировку расчёской.
Коротко про пузырьковую сортировку
Самый простой способ сортировки, который работает по такому принципу: берутся два элемента, сравниваются между собой и сразу меняются местами, если второй больше первого. Называется так потому, что это похоже на пузырьки воздуха в воде, которые всплывают наверх.
Если представить числа в виде столбиков, в зависимости от их размера, то пузырьковая сортировка будет выглядеть так:
Чем плоха пузырьковая сортировка
Главный недостаток пузырьковой сортировки — её скорость и полный перебор всех элементов массива. Скорость работы алгоритма зависит не от количества сравнений (они выполняются быстро), а от количества перестановок (на них как раз и тратится много процессорного времени).
Получается, что если у нас в массиве в начале будет много больших элементов, которые нужно отправить в конец массива, то каждый раз нам придётся менять их местами с соседями, по одной перестановке за раз. Можно представить, что мы несем куда-то не слишком тяжёлый ящик, но после каждого шага ставим этот ящик на пол, потом поднимаем, делаем шаг, снова ставим, снова поднимаем. Процедуры простые, но из-за устройства алгоритма мы делаем эти процедуры слишком много раз.
Best Horse Racing Handicapping Tutorial and Tips
В чём хитрость сортировки расчёской
Раз у нас большие элементы могут тормозить весь процесс, то можно их перекидывать не на соседнее место, а подальше. Так мы уменьшим количество перестановок, а с ними сэкономим и процессорное время, нужное на их обработку.
Но отправлять каждый большой элемент сразу в конец массива будет недальновидно — мы же не знаем, насколько этот элемент большой по сравнению с остальными элементами. Поэтому в сортировке расчёской сравниваются элементы, которые отстоят друг от друга на каком-то расстоянии. Оно не слишком большое, чтобы сильно не откидывать элементы и возвращать потом большинство назад, но и не слишком маленькое, чтобы можно было отправлять не на соседнее место, а чуть дальше.
Опытным путём программисты установили оптимальное расстояние между элементами — это длина массива, поделённая на 1,247 (понятное дело, расстояние нужно округлить до целого числа). С этим числом алгоритм работает быстрее всего.
Как работает алгоритм сортировки расчёской
На первом шаге мы находим длину массива (например, 10 элементов) и делим её на 1,247. Допустим, после округления у нас получилось число 8. Теперь мы проходим первый цикл пузырьковой сортировки, только сравнивая не 1 и 2, 2 и 3, а сразу 1 и 8, 2 и 9, 3 и 10. Это отправит самые большие числа, если они есть в начале, в самый конец. Всего на первом шаге будет три сравнения.
На втором шаге мы берём число 8 из предыдущего этапа и снова делим его на 1,247, получая число 6. Теперь мы снова проходим весь массив и сравниваем так:
Уже получилось 5 перестановок и снова крупные числа улетели поближе к концу массива.
Trainer gets his reluctant horse to race, and she goes on to win! — Racing TV
Так мы уменьшаем размер шага до тех пор, пока он не станет меньше единицы — к этому моменту массив будет полностью отсортирован.
Сортировка расчёской называется так из-за того, что мы как бы расчёсываем массив сначала широким гребнем (большой шаг), потом гребнем поменьше (шаг поменьше). В конце шаг равен единице, как в пузырьковой сортировке.
Сортировка расчёской на JavaScript
Запустите этот код в консоли браузера, чтобы посмотреть, как алгоритм шаг за шагом приводит массив в нормальный вид:
// исходный массив var arr = [3,14,1,7,9,8,11,6,4,2] // получаем длину массива const l = arr.length; // оптимальное число для вычисления шага сравнения const factor = 1.247; // получаем точный шаг сравнения let gapFactor = l / factor; // пока шаг больше единицы while (gapFactor > 1) < // округляем шаг до целого const gap = Math.round(gapFactor); // и организуем цикл как в пузырьковой сортировке for (let i = 0, j = gap; j < l; i++, j++) < // если сначала идёт большое число if (arr[i] >arr[j]) < // меняем их местами [arr[i], arr[j]] = [arr[j], arr[i]]; >// выводим текущее состояние массива в консоль // это необязательный шаг, он здесь для наглядности console.log(arr); > // в конце цикла рассчитываем новый шаг gapFactor = gapFactor / factor; >
Почему это лучше пузырьковой сортировки, ведь алгоритм выглядит сложнее и в конце мы всё равно сравниваем соседние элементы?
То, что код выглядит сложнее, ничего не значит: нам нужна не оценка сложности кода, а скорость и эффективность работы.
Расчёска лучше пузырьковой сортировки, потому что в ней намного меньше операций перестановки. Именно перестановка занимает основное время процессора. В самом худшем случае алгоритм сортировки расчёской будет работать так же, как и пузырьковая, а в среднем — алгоритм работает быстрее пузырьковой.
Получите ИТ-профессию
В «Яндекс Практикуме» можно стать разработчиком, тестировщиком, аналитиком и менеджером цифровых продуктов. Первая часть обучения всегда бесплатная, чтобы попробовать и найти то, что вам по душе. Дальше — программы трудоустройства.
Источник: thecode.media
Mingiyan / Solution.java
Horse Racing Разберись, что делает программа. Реализуй метод calculateHorsesFinished. Он должен: 1. Посчитать количество финишировавших лошадей и возвратить его. Используй метод isFinished(). 2. Если лошадь еще не пришла к финишу (!isFinished()), то: 2.1.
Вывести в консоль «Waiting for » + horse.getName(). 2.2. Подождать, пока она завершит гонку…
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
package com . javarush . test . level16 . lesson05 . task02 ; |
import java . util . ArrayList ; |
import java . util . List ; |
/* Horse Racing |
Разберись, что делает программа. |
Реализуй метод calculateHorsesFinished. Он должен: |
1. Посчитать количество финишировавших лошадей и возвратить его. Используй метод isFinished(). |
2. Если лошадь еще не пришла к финишу (!isFinished()), то: |
2.1. Вывести в консоль «Waiting for » + horse.getName(). |
2.2. Подождать, пока она завершит гонку. Подумай, какой метод нужно использовать для этого. |
*/ |
public class Solution |
public static int countHorses = 10 ; |
public static void main ( String [] args ) throws InterruptedException |
List < Horse >horses = prepareHorsesAndStart (); |
while ( calculateHorsesFinished ( horses ) != countHorses ) |
> |
> |
public static int calculateHorsesFinished ( List < Horse >horse ) throws InterruptedException |
int countFinished = 0 ; |
//add your implementation here — добавь свою реалзацию тут |
for ( int i = 0 ; i < horse . size (); i ++) |
if ( horse . get ( i ). isFinished ) |
countFinished ++; |
> |
else if ( horse . get ( i ). isFinished () == false ) |
System . out . println ( «Waiting for » + horse . get ( i ). getName ()); |
horse . get ( i ). join (); |
> |
return countFinished ; |
> |
public static class Horse extends Thread |
public Horse ( String name ) |
super ( name ); |
> |
private boolean isFinished ; |
public boolean isFinished () |
return isFinished ; |
> |
public void run () |
String s = «» ; |
for ( int i = 0 ; i < 1001 ; i ++) < //delay |
s += new String ( «» + i ); |
if ( i == 1000 ) |
s = » has finished the race!» ; |
System . out . println ( getName () + s ); |
isFinished = true ; |
> |
> |
> |
> |
public static List < Horse >prepareHorsesAndStart () |
List < Horse >horses = new ArrayList < Horse >( countHorses ); |
String number ; |
for ( int i = 1 ; i < countHorses + 1 ; i ++) |
number = i < 10 ? ( «0» + i ) : «» + i ; |
horses . add ( new Horse ( «Horse_» + number )); |
> |
for ( int i = 0 ; i < countHorses ; i ++) |
horses . get ( i ). start (); |
> |
return horses ; |
> |
> |
Источник: gist.github.com
JavaRush. Решение задачи «Horse Racing. Калюта Вова, 9 лет.
× Вам не понравилось видео. Спасибо за то что поделились своим мнением!
Издатель Feb 15, 2021
Условие:
Разберись, что делает программа.
Реализуй метод calculateHorsesFinished.
Он должен:
1. Посчитать количество финишировавших лошадей и возвратить его. Используй метод isFinished().
2. Если лошадь еще не пришла к финишу (!isFinished()), то:
2.1. Вывести в консоль «Waiting for » + horse.getName().
2.2. Подождать, пока она завершит гонку. Подумай, какой метод нужно использовать для этого.
2.3. Не считать такую лошадь финишировавшей.
Требования:
• Метод calculateHorsesFinished должен вернуть количество финишировавших лошадей.
• Метод calculateHorsesFinished должен вызывать метод isFinished у каждой лошади из переданного списка.
• Если какая-либо из переданных в списке лошадей еще не финишировала, метод calculateHorsesFinished должен вывести в консоль «Waiting for » + horse.getName(). Пример сообщения для первой лошади: «Waiting for Horse_01».
• Если какая-либо из переданных в списке лошадей еще не финишировала, метод calculateHorsesFinished должен подождать пока она финиширует. Используй правильный метод для ожидания.
• После завершения работы программы, консоль должна содержать информацию о том, что все лошади финишировали. Пример сообщения для первой лошади: «Horse_01 has finished the race!».
Комментариев нет.
Следующее
JavaRush. Решение задачи «Рефакторинг (11)». Калюта Вова, 9 лет.
от admin 2 года назад 9 Просмотры
JavaRush. Решение задачи «Sokoban (6)». Калюта Вова, 9 лет.
от admin 2 года назад 1 Просмотры
JavaRush. Решение задачи «Sokoban (9)». Калюта Вова, 9 лет.
от admin 2 года назад 1 Просмотры
JavaRush. Решение задачи «Sokoban (10)». Калюта Вова, 9 лет.
от admin 2 года назад 25 Просмотры
JavaRush. Решение задачи «Рефакторинг (9)». Калюта Вова, 9 лет.
от admin 2 года назад 1 Просмотры
JavaRush. Решение задачи «POST, а не GET». Калюта Вова, 9 лет.
от admin 2 года назад 3 Просмотры
JavaRush. Решение задачи «CashMachine (1)». Калюта Вова, 9 лет.
от admin 2 года назад 2 Просмотры
JavaRush. Решение задачи «Мне нравится курс JavaRush». Калюта Вова, 9 лет.
от admin 2 года назад 8 Просмотры
JavaRush. Решение задачи «Чат (9)». Калюта Вова, 9 лет.
от admin 2 года назад 6 Просмотры
Достиг 32 УРОВНЯ в JAVARUSH. Урааа! JavaRush. Решение задачи «CashMachine 2». Калюта Вова, 9 лет.
от admin 2 года назад 7 Просмотры
JavaRush. Решение задачи «Тетрис (1-3)». Калюта Вова, 9 лет.
от admin 2 года назад 2 Просмотры
JavaRush. Решение задачи «Чат (11)». Калюта Вова, 9 лет.
от admin 2 года назад 3 Просмотры
JavaRush. Решение задачи «2048 (1)». Калюта Вова, 9 лет.
от admin 2 года назад 1 Просмотры
JavaRush. Решение задачи «2048 (2)». Калюта Вова, 9 лет.
от admin 2 года назад 1 Просмотры
JavaRush. Решение задачи «isPowerOfThree». Калюта Вова, 9 лет.
от admin 2 года назад 1 Просмотры
JavaRush. Решение задачи «Свойства URL». Калюта Вова, 9 лет.
от admin 2 года назад 7 Просмотры
JavaRush. Решение задачи «Sokoban (1)». Калюта Вова, 9 лет.
от admin 2 года назад 11 Просмотры
33 УРОВЕНЬ НА JAVARUSH! JavaRush. Решение задачи «Sokoban (2)». Калюта Вова, 9 лет.
от admin 2 года назад 14 Просмотры
JavaRush. Решение задачи «Чат (5)». Калюта Вова, 9 лет.
от admin 2 года назад 2 Просмотры
JavaRush. Решение задачи «Чат (6)». Калюта Вова, 9 лет.
от admin 2 года назад 5 Просмотры
7.5 Упорядоченные цифры. «Поколение Python»: курс для начинающих. Курс Stepik
от admin 1 год назад 2,774 Просмотры
Источник: best-coding.ru