Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Сорт_методы.doc
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
267.78 Кб
Скачать

Void floatRadixSort (t* &in, long n) {

T *out = new T[N];

ushort i;

long *counters = new long[sizeof(T)*256], *count;

createCounters(in, counters, N);

for (i=0; i<sizeof(T)-1; i++) {

count = counters + 256*i;

if ( count[0] == N ) continue;

radixPass (i, N, in, out,count);

swap(in, out);

}

count = counters + 256*i;

floatRadixLastPass (i, N, in, out,count);

delete in;

in = out;

delete counters;

}

Для большего удобства можно объединить все полученные сортировки в одну функцию с дополнительным параметром type = {FLOAT, SIGNED, UNSIGNED}, в зависимости от входного типа данных.

Эффективность поразрядной сортировки

Рост быстрой сортировки мы уже знаем: O(nlogn). Судя по оценке, поразрядная сортировка растет линейным образом по n, так как k,m - константы. Также она растет линейным образом по k - при увеличении длины типа(количества разрядов) соответственно возрастает число проходов. Однако, в последний пункт реальные условия вносят свои коррективы. Дело в том, что основной цикл сортировки по i-му байту состоит в движении указателя uchar* bp шагами sizeof(T) по массиву для получения очередного разряда. Когда T=char, шаг равен 1, T=short - шаг равен 2, T=long - шаг равен 4... Чем больше размер типа, тем менее последовательный доступ к памяти осуществляется, а это весьма существенно для скорости работы. Поэтому реальное время возрастает чуть быстрее, нежели теоретическое.

Кроме того, поразрядная сортировка уже по своей сути неинтересна для малых массивов. Каждый проход содержит минимум 256 итераций, поэтому при небольших n общее время выполнения (n+m) определяется константой m=256.

Поведение неестественно, так как проходы выполняются полностью, вне зависимости от исходного состояния массива. Поразрядная сортировка является устойчивой.

Результаты тестирования

На диаграммах изображены результаты сравнений поразрядной сортировки (синяя линия) и быстрой(розовая линия), причем использовалась функция sort() из библиотеки STL.

  • short Благодаря малой разрядности и простоте внутренних циклов, поразрядная перегнала быструю сортировку уже на 100 элементах.

  • long При переходе к типу long произошло двукратное увеличение количества проходов RadixPass, поэтому худшая асимптотика быстрой сортировки показала себя лишь после 600 элементов, где она начала отставать.

  • float По графику видно, что для этого типа поразрядная сортировка оказалась гораздо эффективнее, нежели для long. В чем дело, ведь размер одинаков - 4 байта ? Оказывается, на типе float резко возрастает время работы быстрой сортировки. Возможно, это связано с тем, что процессор, прежде чем делать какие-либо операции, переводит его в double, а потом работает с этим типом, который 2 раза больше по размеру.. Так или иначе, быстрая сортировка стала работать в 2 раза медленнее, и поразрядная вышла вперед после 100 элементов.

  • double График показан с десятикратным увеличением. Размер типа увеличился в 2 раза, поэтому для небольших n поразрядная сортировка, конечно, отстает, но перегоняет быструю на массивах из нескольких тысяч элементов. Небольшое преимущество radixSort длится приблизительно до 16000 элементов, когда данные начинают вылезать за пределы кэша. Соответственно, начинает играть роль медленный непоследовательный доступ (с шагами по 8 байт) к основной памяти.. В результате поразрядная сортировка снова выбивается вперед лишь после 500000 элементов.

Сортировка экстремумами

Придумал вот такой устойчивый алгоритм сортировки, сложность O(n^2). Идея вот в чём: допустим, нам нужно отсортировать массив по возрастанию. Для этого мы находим его минимальный элемент, добавляем его в массив-результат, а самому минимальному элементу из исходного массива присваиваем плюс бесконечность либо удаляем его. Если необходимо сортировать по возрастанию, находим максимальный элемент и присваиваем минус бесконечность. Псевдокод:

Код:

sort(arr) {

result = [];

цикл по arr по итератору i:

j = индексМинЭлемента;

result[i] = arr[j];

arr[j] = Infinity;

возврат result;

}

Пример реализации на javascript:

Код:

function sort(array) {

var result = [];

for (var i = 0; i < array.length; i++) {

var min = array[0], n = 0;

for (var j = 0; j < array.length; j++)

if (array[j] < min)

min = array[j], n = j;

result.push(min);

array[n] = Infinity;

}

return result;

}

Баян или нет?

10.04.2011, 14:12

гостъ

да

10.04.2011, 15:17

Новичок

Жаль.