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

9.2.4. Внутренняя сортировка

Различают внутреннюю и внешнюю сортировку. Под внутрен­ней сортировкой понимают сортировку в условиях, когда вся таблица помещается в оперативную память. Внешняя сортировка – это сортировка данных на внешнем носителе, причем доступный объем оперативной памяти недостаточен для того, что считать сразу всю таблицу в оперативную память.

9.2.4.1. Сортировка подсчетом

Этот простой метод основан на том, что j-й ключ в сортирован­ной последовательности превышает ровно j-1 ключ. В первой фазе алгоритм подсчитывает для каждого ключа число ключей, которые меньше его. Значение счетчика для ключа и есть тот номер позиции в сортированной таблице, который он должен занять.

Void CountSort(int n, int t[]){

// t – сортируемый массив целых чисел длиной n

int i,j;

int *c=new int[n]; // массив счетчиков

// обнулим счетчики

for(i=0; i<n; i++) c[i]=0;

// фаза подсчета

for(i=0; i<n; i+){

for(j=0; j<i; j++){

if(t[i]>t[j]){

c[i]++;

} else {

c[j]++;

}

}

}

// фаза расстановки

for(i=0; i<n; i++){

while(i!=c[i]){ // до тех пор, пока t[i] не займет

// окончательного положения

swap(t[i],t[c[i]]); // обмен местами эл-тов таблицы

swap(c[i],c[c[i]]); // обмен местами счетчиков

}

}

}

Ключ ti в исходной последовательности сравнивается с i предшест­вующими ключами и, следовательно, общее число сравнений равно

то есть пропорционально N2.

9.2.4.2. Сортировка простым выбором

Просматривая исходную последовательность ключей t, начиная с t0, находим среди них наименьший и меняем местами с t0, затем повторяем процесс начиная с t1, находим наименьший и меняем местами с t1, и так далее до конца таблицы. Ниже представлен текст функции, выполняющей сортировку простым выбором.

Void SimpleChoice(int n, int t[]){

int i,j,k;

for(i=0; i<n; i++){

k=i;

// к моменту завершения цикла по j, k будет индексом

// наименьшего ключа на отрезке iN-1

for(j=i+1;j<n;j++){

if(t[j]<t[k]){

k=j;

}

}

swap(t[i], t[k]);

}

}

В этом случае время также пропорционально N2, так как при поиске наименьшего ключа на отрезке iN-1, потребуется выполнить N-i-1 сравнений. Суммируя по i, получим величину, пропорциональную N2.

9.2.4.3. Квадратичный выбор

Б ыстродействие сортировки выбором можно улучшить, если сделать процесс выбора многоступенчатым. Пусть размер таблицы N=16. Разобьем таблицу на 4 группы по 4 элемента в каждой, как на рис 32

Рис 32. Квадратичный выбор

Определим наибольший элемент в каждой группе и поместим его в отдельную группу "лидеров". Наибольший среди них и есть наибольший в таблице. Поместим его в область вывода. Последующие элементы отыскиваются так: среди элементов группы, из которой происходил выбранный на предыдущем шаге элемент, выбираем наибольший и помещаем вместо выбывшего в группу лидеров. Затем очередной элемент выводится из группы лидеров. Если N – точный квадрат, то можно разделить таблицу на групп по элементов. Любой выбор, кроме первого потребует не более сравнений внутри группы ранее выбранного элемента плюс сравнений внутри группы лидеров. Таким образом, время такой сортировки пропорционально , что гораздо лучше N2. Эту идею можно обобщить, получив метод кубического выбора, выбора четвертой степени и т.д.

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