Программирование на языке СИ Сервер Информационных Технологий

содержит море(!) аналитической информации Сервер поддерживается

Центром Информационных Технологий

(095) 932-9212, 932-9213, 939-0783

E-mail: info@citforum.ru

2.2. Сортировка И Слияние Списков При работе со списками очень часто возникает необходимость перестановки элементов списка в определенном порядке. Такая задача называется сортировкой списка и для ее решения существуют различные методы. Рассмотрим некоторые из них. 2.2.1. Пузырьковая сортировка Задача сортировки заключается в следующем: задан список целых чисел (простейший случай) В=< K1, K2,..., Kn >. Требуется переставить элементы списка В так, чтобы получить упорядоченный список B'=< K'1, K'2,...,K'n >, в котором для любого 1 имеем: B=< 20,-5,10,8,7> B'=< > B=< -5,10,8,7 > B'=< 20 > B=< 10,8,7 > B'=< -5,20 > B=< 8,7 > B'=< -5,10,20 > B=< 7 > B'=< -5,8,10,20 > B=< > B'=< -5,7,8,10,20 > Функция insert реализует сортировку вставкой. /* сортировка методом вставки */ float *insert(float *s, int m, int n) { int i,j,k; float aux; for (i=m+1; i=2 упорядоченных списков B1,B2,...,Bm заменяется на М/2 (или (М+1)/2) упорядоченных списков, B(2i-1)-oго и B(2i)-ого ( 2i реорганизуется в список B',< K1 >,B", где В' - подсписок В с элементами, не большими К1, а В" - подсписок В с элементами, большими К1. В списке B',< K1 >,B" элемент К1 расположен на месте, на котором он должен быть в результирующем отсортированном списке. Далее к спискам B' и В" снова применяется упорядочивание быстрой сортировкой. Приведем в качестве примера сортировку списка, отделяя упорядоченные элементы косой чертой, а элементы Ki знаками < и >. Пример: 9, 7, 18, 3, 52, 4, 6, 8, 5, 13, 42, 30, 35, 26 7, 3, 4, 6, 8, 5/ / 18, 52, 13, 42, 30, 35, 26 3, 4, 6, 5// 8/ 9/ 13/ / 52, 42, 30, 35, 26 / 4, 6, 5/ 7/ 8/ 9/ 13/ 18/ 42, 30, 35, 26/ 3/ / 6, 5/ 7/ 8/ 9/ 13/ 18/ 30, 35, 26/ / 52 3/ 4/ 5/ / 7/ 8/ 9/ 13/ 18/ 26/ / 35/ 42/ 52 Время работы по сортировке списка методом быстрой сортировки зависит от упорядоченности списка. Оно будет минимальным, если на каждом шаге разбиения получаются подсписки B' и В" приблизительно равной длины, и тогда требуется около N*log2(N) шагов. Если список близок к упорядоченному, то требуется около (N*N)/2 шагов. Рекурсивная функция quick упорядочивает участок массива s быстрой сортировкой. /* быстрая сортировка */ double * quick(double *s,int low,int hi) { double cnt,aux; int i,j; if (hi>low) { i=low; j=hi; cnt=s[i]; while(i < j) { if (s[i+1]=0, т.е. D(j,n)=floor(n/m)%10, где m=10^(j-1). Пусть В0,В1,...,В9 - вспомогательные списки (карманы), вначале пустые. Для реализации распределяющей сортировки выполняется процедура, состоящая из двух процессов, называемых распределение и сборка для j=1,2,...,T. PАСПРЕДЕЛЕНИЕ заключается в том, что элемент Кi (i=1,N) из В добавляется как последний в список Bm, где m=D(j,Ki), и таким образом получаем десять списков, в каждом из которых j-тые разряды чисел одинаковы и равны m. СБОРКА объединяет списки В0,В1,...,В9 в этом же порядке, образуя один список В. Рассмотрим реализацию распределяющей сортировки при Т=2 для списка: B= . РАСПРЕДЕЛЕНИЕ-1: B0=, B1=< >, B2=, B3=, B4=, B5=, B6=,B7=, B8=, B9=. СБОРКА-1: B= РАСПРЕДЕЛЕНИЕ-2: B0=, B1=, B2=, B3=, B4=, B5=, B6=< >,B7=< >,B8=< >, B9=< >. СБОРКА-2: B=. Количество действий, необходимых для сортировки N T-цифровых чисел, определяется как Q(N*T). Недостатком этого метода является необходимость использования дополнительной памяти под карманы. Однако можно исходный список представить как связанный и сортировку организовать так, чтобы для карманов В0,В1,...,В9 не использовать дополнительной памяти, элементы списка не перемещать, а с помощью перестановки указателей присоединять их к тому или иному карману. В представленной ниже программе функция pocket реализует распределяющую сортировку связанного линейного списка (указатель q), в котором содержатся Т-разрядные десятичные положительные числа, без использования дополнительной памяти; в функции a[i], b[i] указывают соответственно на первый и на последний элементы кармана Bi. /* вызов распределяющeй сортировки списка */ #include #include typedef struct str { long val; struct str *n; } SP1; main() { int i; SP1 *q=malloc(sizeof(SP1)),*r; SP1 *pocket(SP1 * ,int ); long a[14]={ 0,7,18,3,52,4,6,8,5,13,42,30,35,26 }; q->n=NULL; q->val=a[0]; r=q; printf(" %d",a[0]); for(i=1;in=malloc(sizeof(SP1)); r->val=a[i]; (r->n)->n=NULL; r=r->n; printf(" %d",a[i]); } r=pocket(q,2); printf("\n"); /* печать результатов */ while (r!=NULL) { printf(" %d",r->val); r=r->n; } } /* распределяющая сортировка списка */ SP1 *pocket(SP1 *q,int t) { int i,j,k,m=1; SP1 *r, *gg, *a[10], *b[10]; gg=q; for(j=1;jn=q; r=b[k]=q; q=q->n; r->n=NULL; } for(i=0;i

Соседние файлы в папке Программирование на языке Си (Ю.Ю.Громов, С.И.Татаренко)