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

2.4. Быстрая сортировка на языке Java

В Java ситуация другая. В ранних версиях не было стандартной функции сортировки, поэтому приходилось писать собственную. В последних версиях появилась такая функция, работающая с клас­сами, реализующими интерфейс Comparable, поэтому теперь мы мо­жем просить библиотеку сортировать то, что нам потребуется. Но по­скольку используемые технологии полезны и в других ситуациях, в данном разделе мы опишем все детали реализации быстрой сорти­ровки в Java.

Адаптировать быструю сортировку для каждого конкретного типа данных легко; однако же более поучительно написать обобщенную фун­кцию для сортировки объектов любых типов, что больше похоже на ин­терфейс qsort.

Одно из крупных отличий от С и C++ заключается в том, что в Java мы не можем передать функцию сравнения в другую функцию — здесь не существует указателей на функции. Вместо этого мы создаем интер­фейс (interface), единственным содержимым которого будет функция, сравнивающая два объекта типа Obj ect. Далее для каждого сортируемо­го типа данных мы создаем класс с функцией (методом), которая реали­зует интерфейс для этого типа данных. Мы передаем экземпляр класса в функцию сортировки, которая в свою очередь использует функцию сравнения из этого класса для сравнения элементов.

Сначала опишем интерфейс Cmp, который определяет единственную функцию стр, сравнивающую два значения типа Object:

interface Cmp {

int cmp(0bject x, Object y);

}

Теперь мы можем написать функции сравнения, которые реализуют этот интерфейс; например, следующий класс определяет функцию, сравнивающую объекты типа Integer:

// Icmp: сравнение целых

class Icmp implements Cmp {

public int cmp(0bject o1, Object o2)

{

int i1 = ((Integer) o1).intValue();

int i2 = ((Integer) o2).intValue();

if (i1< i2)

return –1;

else if (i1 == i2)

return 0;

else

return 1;

{

}

а эта функция сравнивает объекты типа St ring:

// Scmp: сравнение строк

class Scmp implements Cmp {

public int cmp(0bject o1, Object o2)

{

String s1 = (String) o1;

String s2 = (String) o2;

return s1,compareTo(s2);

}

}

Данным способом можно сортировать только типы, наследуемые от клас­са Object; подобный механизм нельзя применять для базовых типов, таких как int или double. Поэтому мы сортируем элементы типа Integer, а не int.

С этими компонентами мы теперь можем перенести функцию быст­рой сортировки из языка С в Java и вызывать в ней функцию сравне­ния из объекта Cmp, переданного параметром. Наиболее существенное изменение — это использование индексов left и right, поскольку в Java нет указателей на массивы.

// Quicksort.sort: сортировать vfleft]..v[right]

// алгоритмом quicksort

static void sort(0bject[] v, int left, int right, Cmp cmp)

{

int i, last;

if (left >= right) // ничего делать не надо

return;

swap(v, left, rand(left, right)); // поместить разделитель

last = left; // в v[left]

for (i = left+1; i <= right; i++) // разделить массив

if (cmp.cmp(v[i], v[left]) < 0)

swap(v, ++last, i);

swap(v, left, last); // вернуть разделитель

sort(v, left, last-1, cmp); // рекурсивно отсортировать

sort(v, last+1, right, cmp); // обе части

}

Quicksort.sort использует cmp для сравнения двух объектов и, как и рань­ше, вызывает swap для их обмена.

// Quicksort.swap: обменять v[i] и v[j]

static void swap(0bject[] v, int i,.int j)

{

Object temp;

temp = v[i];

v[i] = v[j];

v[j] = temp;

}

Генерация случайного номера происходит в функции rand, которая возвращает случайное число в диапазоне с left пo right включительно:

static Random rgen = new Random();

// Quicksort.rand: возвращает случайное целое число

// из [left, right]

static int rand(int left, int right)

{

return left + Math.abs(rgen.nextlnt())%(right-left+1);

}

Мы вычисляем абсолютное значение (используя функцию Math.abs), поскольку в Java генератор случайных чисел возвращает как положи­тельные, так и отрицательные значения.

Функции so rt, swap и rand, а также объект-генератор случайных чисел rgen являются членами класса Quicksort.

Наконец мы готовы написать вызов Quicksort, sort для сортировки массива типа String:

String[] sarr = new String[n];

// заполнить n элементов sarr...

Quicksort.sort(sarr, 0, sarr. length-1, newScmp0);

Так вызывается sort с объектом сравнения строк, созданным для этой цели.

Упражнение 2-2

Наша реализация быстрой сортировки в Java делает несколько преоб­разований типов, сначала переводя исходные данные из их первоначаль­ного типа (вроде Integer) в Object, а затем обратно. Поэксперименти­руйте с версией Quicksort. sort, которая использует конкретный тип при сортировке, и попробуйте вычислить, какие потери производительности вызываются преобразованием типов.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]