Нормальный быстрый сортировка
Найдите основание базового значения, а затем сортируйте ее в одной поездке, чтобы числа слева от основания меньше основания, а цифры справа от основания превышают или равны основанию. Затем разделите его на две Subarrays Sorting. Рекурсивный такой.
Public Class QuickSort {public static <T Extens сопоставимо <? Super t >> void sort (t [] arr) {sort (arr, 0, arr.length - 1);} public static <t Extens сопоставимо <? Super t >> void sort (t [] arr, int left, int rair) {if (left> = raver) return; int p = раздел (arr, слева, справа); sort (arr, left, p - 1); sort (arr, p + 1, справа);} private static <t выдвигает сопоставимые <? Super t >> int partition (t [] arr, int left, int raight) {t base = arr [слева]; int j = слева; for (int i = слева+1; i <= right; i ++) {if (base.com ppareto (arr [i])> 0) {j ++; Swap (arr, j, i);}} swap (arr, arr, rath j); Сортировка} public static void swap (Object [] arr, int i, int j) {if (i! = j) {Object temp = arr [i]; arr [i] = arr [j]; arr [j] = temp;}} private void princarr (объект [] arr) {for (объект o: arr) {System.out.print (o); System.out.print ("/t");} System.out.println ();} public static void main (String args []) {integer [] arr = {3, 5, 1, 7, 2, 9, 8, 0, 4, 6}; prantarr (arr);//3 1 7 2 9 8 0 4 8 0 4. 6sort (arr); prantarr (arr); // 0 1 2 3 4 5 6 7 8 9}}Быстрая оптимизация сортировки: случайным образом выберите базовую базовую базу
Когда массив почти упорядочен, производительность быстрого порядка плохая (потому что после каждого порядка рекурсивный размер левого и правого субботних сильно отличается, а большая часть, вероятно, достигнет O (n^2) в конце).
Решение: ссылочное значение выбирается случайным образом, вместо того, чтобы каждый раз принимать первое число. Это не будет нарушено «почти упорядоченными массивами». Но производительность сортировки «почти вне порядка матриц» может немного упасть, по крайней мере, до сортировки есть больше части. Этот обмена не имеет смысла в вне порядка ... Есть много компонентов «удачи» ...
Public Class QuickSort {public static <T Extens сопоставимо <? Super t >> void sort (t [] arr) {sort (arr, 0, arr.length - 1);} public static <t Extens сопоставимо <? Super t >> void sort (t [] arr, int left, int rair) {if (left> = raver) return; int p = раздел (arr, слева, справа); sort (arr, left, p - 1); sort (arr, p + 1, справа);} private static <t выдвигает сопоставимые <? Super t >> int partition (t [] arr, int left, int right) {// Перед сортировкой, пусть опорное значение будет обменено со случайным числом. Таким образом, эталонное значение является случайным. // это не приведет к тому, что рекурсивная шкала левой и правой стороны будет непоследовательной, когда массив относительно упорядочен, что приводит к худшему свопу сложности времени (arr, слева, (int) (math.random ()*(справа - слева+1)+слева)); t base = arr [слева]; int j = слева; (base.compareto (arr [i])> 0) {j ++; swap (arr, j, i);}} swap (arr, left, j); return j; // возвращать нижний угол контрольного значения после лживого сортировки} public static void swap (объект] arr, int i, int j) {if (i! temp;}}private static void printArr(Object[] arr) {for (Object o : arr) {System.out.print(o);System.out.print("/t");}System.out.println();}public static void main(String args[]) {Integer[] arr = {3, 5, 1, 7, 2, 9, 8, 0, 4, 6}; prantarr (arr); // 3 5 1 7 2 9 8 0 4 6sort (arr); prantarr (arr); // 0 1 2 3 4 5 6 7 8 9}}}Быстрая сортировка продолжает оптимизировать: используйте сортировку вставки в сочетании
Быстрое упорядочение заключается в том, чтобы непрерывно уменьшать масштаб проблемы для решения суб-спортив и требует непрерывной рекурсии. Однако рекурсия достаточно мала, и если эта нестабильная + рекурсия продолжает выполняться, эффективность может быть не очень хорошей.
Поэтому, когда проблема невелика и почти упорядочена, сортировка вставки работает хорошо. Вы часто можете увидеть такие комментарии в Arrays.sort (), которая поставляется с Java: «Используйте вставку сортировки на крошечных массивах», «Вставка сортировки на самых маленьких массивах»
Public Class QuickSort {public static <T Extens сопоставимо <? Super t >> void sort (t [] arr) {sort (arr, 0, arr.length - 1, 16);}/*** @param arr Array для сортировки* @param слева влево* @param справа вправо. Распространяет сопоставимо <? Super t >> void sort (t [] arr, int left, int right, int k) {// часы масштабирования сортируются с помощью вставки if (right - левый <= k) {insertionsort (arr, слева, справа); return;} int p = partition (arr, слева, справа); сортировка (arr, слева, p - 1, k); sort (arr, p + 1, right, right, k); Super T >> void insertionst (t [] arr, int l, int r) {for (int i = l + 1; i <= r; i ++) {t cur = arr [i]; int j = i-1; for (; j> = 0 && cur.compareto (arr [j]) <0; j--) {arr + 1] = arr [rAr arr [j]) <0; r. <T расширяется сопоставимо <? Super T >> int partition (t [] arr, int left, int right) {// Перед сортировкой, пусть обмен ссылочными значениями со случайным числом. Таким образом, эталонное значение является случайным. // это не приведет к тому, что рекурсивная шкала левой и правой стороны будет непоследовательной, когда массив является относительно порядком, что приводит к худшему свопу сложности времени (arr, слева, (int) (math.random () * (справа - слева + 1) + слева)); t base = arr [слева]; int j = слева; для (int i = слева + 1; (base.compareto (arr [i])> 0) {j ++; swap (arr, j, i);}} swap (arr, left, j); return j; // возвращать нижний угол базового значения после лживой сортировки} public void swap (объект] arr, int i, int j) {if (i! temp;}}private static void printArr(Object[] arr) {for (Object o : arr) {System.out.print(o);System.out.print("/t");}System.out.println();}public static void main(String args[]) {Integer[] arr = {3, 5, 1, 7, 2, 9, 8, 0, 4, 6}; prantarr (arr); // 3 5 1 7 2 9 8 0 4 6sort (arr); prantarr (arr); // 0 1 2 3 4 5 6 7 8 9}}}Быстрая сортировка продолжает оптимизировать: двустороннее быстрое сортировку
В начальной нормальной быстрой сортировке говорится, что базовое значение на левой стороне основания меньше основания, а основание на правой стороне больше или равна основанию. Они, равные базе, будут собираться вправо (или слегка изменяют отношения размера, соберутся слева). Во всяком случае, это сорвается в сторону. Когда в массиве повторяется много чисел, это приведет к огромной разнице в размере двух подводных лодков. В настоящее время я хочу назначить числа, равные базе, обеим сторонам базы, вместо того, чтобы собрать их вместе.
(Примечание: при тестировании кода лучше всего отвлечься от части вставки и выглядеть как в моем коде ниже ... в противном случае, когда объем данных меньше, чем k = 16, выполняется сортировка вставки ...)
Public Class QuickSort {public static <T Extens сопоставимо <? Super t >> void sort (t [] arr) {sort (arr, 0, arr.length - 1, 16);}/*** @param arr Array для сортировки* @param слева влево* @param справа вправо. Распространяет сопоставимо <? Super t >> void sort (t [] arr, int lets, int rair, int k) {// insertionort (arr, rath, right, справа); // return; //} if (слева> = правый) return; int p = раздел (arr, слева, справа); сортировка (arr, слева, справа); сортировка (arr, левый, p - 1, k); sort (arr, p + 1, right, правый, k); Super T >> void insertionst (t [] arr, int l, int r) {for (int i = l + 1; i <= r; i ++) {t cur = arr [i]; int j = i-1; for (; j> = 0 && cur.compareto (arr [j]) <0; j--) {arr + 1] = arr [rAr arr [j]) <0; r. <T расширяется сопоставимо <? Super T >> int partition (t [] arr, int left, int right) {// Перед сортировкой, пусть обмен ссылочными значениями со случайным числом. Таким образом, эталонное значение является случайным. // это не приведет к тому, что рекурсивные масштабы левой и правой стороны будут противоречивыми, когда массив относительно упорядочен, что приводит к наихудшему свопу сложности времени (ARR, слева, (int) (math.random () * (справа - слева + 1) + слева); t Base = Arr [слева]; // Базовое значение, закрыто это контрольное значение, см. Взлостное значение, см. Взлостное значение. влево+1; // Для [слева+1 ......... Правый] интервал, упомянутый в предыдущей строке, я имею в виду [слева+1 ...... i) Левый закрытый правый разомкнутый интервал меньше или равна основанию. int j = справа; // Для [слева+1 ...... справа], упомянутый в двух предыдущих строках, j означает, что значения (j ...... справа] влево открытые и правые закрытые интервалы превышают или равны основанию. В то время как (true) {// сканировать слева направо, сканируйте первый элемент, больше, чем базовый, и затем я останавливаюсь там. Оставо, сканируйте первый элемент, меньший, чем база, а затем J останавливается там. Сортировка} public static void swap (Object [] arr, int i, int j) {if (i! = j) {Object temp = arr [i]; arr [i] = arr [j]; arr [j] = temp;}} private void princarr (объект [] arr) {for (объект o: arr) {System.out.print (o); System.out.print ("/t");} System.out.println ();} public static void main (String args []) {integer [] arr = {3, 5, 1, 7, 2, 9, 8, 0, 4, 6}; prantarr (arr);//3 1 7 2 9 8 0 4 8 0 4. 6sort (arr); prantarr (arr); // 0 1 2 3 4 5 6 7 8 9}}Продолжайте оптимизировать быструю сортировку: две быстрые сортировки не требуют обмена, используйте обмен
Когда вышеупомянутые два пути находят значения, превышающие базовые, и значения меньше, чем базовые, они используют метод Swap () для обмена. Двухметный обмен включает в себя работу третьей переменной температуры, с большей работой чтения и записи. Затем используйте метод прямого назначения, чтобы поместить меньше, чем справа и больше, чем слева. Когда я и J встречаются, эта позиция должна быть размещена. Эта поездка завершена. Просто вспоминать.
Public Class QuickSort {public static <T Extens сопоставимо <? Super t >> void sort (t [] arr) {sort (arr, 0, arr.length - 1, 16);}/*** @param arr Array для сортировки* @param слева влево* @param справа вправо. Распространяет сопоставимо <? Super t >> void sort (t [] arr, int lets, int rair, int k) {// insertionort (arr, rath, right, справа); // return; //} if (слева> = правый) return; int p = раздел (arr, слева, справа); сортировка (arr, слева, справа); сортировка (arr, левый, p - 1, k); sort (arr, p + 1, right, правый, k); Super T >> void insertionst (t [] arr, int l, int r) {for (int i = l + 1; i <= r; i ++) {t cur = arr [i]; int j = i-1; for (; j> = 0 && cur.compareto (arr [j]) <0; j--) {arr + 1] = arr [rAr arr [j]) <0; r. <T расширяется сопоставимо <? Super T >> int partition (t [] arr, int left, int right) {// Перед сортировкой, пусть обмен ссылочными значениями со случайным числом. Таким образом, эталонное значение является случайным. // это не приведет к тому, что рекурсивные масштабы левой и правой стороны будут противоречивыми, когда массив относительно упорядочен, что приводит к худшему свопу сложности времени (ARR, слева, (int) (Math.Random () * (справа-слева + 1) + слева); t Base = Arr [слева]; // Базовое значение, добавляя это значение каждые время. i = слева; // Для [слева+1 ......... справа], упомянутый в предыдущей строке, я имею в виду [слева+1 ...... i) Значения с правой закрытыми, закрытыми с левой головой, меньше или равны основанию. int j = right; // для [слева+1 ...... справа], упомянутый в двух предыдущих строках, j означает, что значения (j ...... справа] слева-открытые и правые прокляты j-; arr [i] = arr [j]; // Сканирование слева направо, сканируйте первый элемент, больше, чем основа, а затем я останавливается там. i, int j) {if (i! = j) {object temp = arr [i]; arr [i] = arr [j]; arr [j] = temp;}} private static void printarr (object [] arr) {for (Object o: arr) {System.out.print (o); System.out.print ("/T") System.out. args []) {integer [] arr = {3, 5, 1, 7, 2, 9, 8, 0, 4, 6}; prantarr (arr); // 3 5 1 7 2 9 8 0 4 6sort (arr); princarr (arr); // 0 1 2 3 4 5 6 7 8 9}}}Быстрая сортировка продолжает оптимизировать: когда используется большое количество данных и множество повторений, используйте трехстороннюю быструю сортировку
Разделите массив на три пути. Первый путь меньше основания, второй путь равен основанию, а третий путь больше, чем основа.
Используйте указатель, чтобы сканировать спереди назад, если:
1. Число, указанное CUR, меньше, чем базовое, то: обмениваться значениями ARR [CUR] и ARR [I], а затем i ++, cur ++.
2. Число, указанное CUR, равно основанию, тогда: cur ++
3. Число, указанное CUR, больше, чем основа, затем: обменивайте значения ARR [CUR] и ARR [J], а затем j--.
Когда Cur> J это означает, что все три пути были завершены.
Public Class QuickSort {public static <T Extens сопоставимо <? Super t >> void sort (t [] arr) {sort (arr, 0, arr.length - 1, 16);}/*** @param arr Array для сортировки* @param слева влево* @param справа вправо. Распространяет сопоставимо <? Super t >> void sort (t [] arr, int left, int rair, int k) {// insertionort (arr, rath, right); // return; //} if (left> = rate) return; int [] ret = раздел (arr, слева, справа); sort (arr, левый, ret [0], k); sort (arr ret [1], справа, k); Super t >> void insertionort (t [] arr, int l, int r) {for (int i = l + 1; i <= r; i ++) {t cur = arr [i]; int j = i-1; for (; j> = 0 && cur.compareto (arr [j]) <0; j--) {arr + 1] = arr [arr [j]) <0; @param arr Array для отсортировки* @param слева левая граница массива для отсортировки* @param справа правой границы массива для сортировки* @param <t> generics* @return*/private static <t Extends сопоставимо <? Super t >> int [] раздел (t [] arr, int left, int right) {// Перед сортировкой, пусть опорное значение будет обменено со случайным числом. Таким образом, эталонное значение является случайным. // это не приведет к тому, что рекурсивные масштабы на левой и правой сторонах будут противоречивыми, когда массив является относительно порядком, что приводит к худшему свопу сложности времени (ARR, слева, (int) (math.random () * (справа - слева + 1) + слева); t Base = arr [слева]; // Основное значение. Следует к этому опорному значению, см. Влево -слева. ряды делятся на следующие три канала (интервалы) int i = слева; // слева указывает, что [lleft ... слева) числа в левом закрытом прямоугольнике в правом интервале меньше, чем базовый int j = правый; // слева указывает, что (rright ... правый] Числа в левом и правом закрытом интервациях больше, чем базовые int cur = i; // Использование. (cur <= j) {if (arr [cur] .compareto (base) == 0) {cur ++;} else if (arr [cur] .compareto (base) <0) {swap (arr, cur ++, i ++);} else {swap (arr, cur, j--);} nevate int int [i-1, 1, 1}; и подпрограмма должна только решить левую и справа от i и j} public static void swap (object [] arr, int i, int j) {if (i! = j) {объект Temp = arr [i]; arr [i] = arr [j]; arr [j] = temp;}} частный статический void prantarr (arr) {for (объект o: arr)}} {System.out.print (o); System.out.print ("/t");} System.out.println ();} public static void main (String args []) {integer [] arr = {3, 5, 1, 7, 2, 9, 8, 0, 4, 6}; prantarr (arr);//3 1 7 2 9 8 0 4 8 0 4. 6sort (arr); prantarr (arr); // 0 1 2 3 4 5 6 7 8 9}}Суммировать
Выше приведено подробное объяснение реализации программирования Java быстрого сортировки и кода оптимизации. Я надеюсь, что это будет полезно для всех. Заинтересованные друзья могут продолжать ссылаться на другие связанные темы на этом сайте. Если есть какие -либо недостатки, пожалуйста, оставьте сообщение, чтобы указать это. Спасибо, друзья, за вашу поддержку на этом сайте!