Разделы презентаций


Внешняя сортировка (сортировка последовательностей)

Содержание

Особенности внешней сортировкиПри сортировке сверхбольшого набора данных, который целиком в ОП не помещается приходится использовать внешние файлы. Исходный набор данных хранится во внешнем файле и многократно должен считываться в ОП. В

Слайды и текст этой презентации

Слайд 1Внешняя сортировка (сортировка последовательностей)

Внешняя сортировка (сортировка последовательностей)

Слайд 2Особенности внешней сортировки
При сортировке сверхбольшого набора данных, который целиком в

ОП не помещается приходится использовать внешние файлы. Исходный набор данных

хранится во внешнем файле и многократно должен считываться в ОП. В каждый момент времени в ОП находится лишь часть полного набора. Главным критерием при разработке методов сортировки становится минимизация числа обращений к внешней памяти.
Основой большинства алгоритмов внешней сортировки является принцип слияния двух упорядоченных последовательностей в единый упорядоченный набор.
Особенности внешней сортировкиПри сортировке сверхбольшого набора данных, который целиком в ОП не помещается приходится использовать внешние файлы.

Слайд 3Прямое слияние
Сортировка, называемая прямым слиянием, выполняется следующим образом:
1. Последовательность А

разбивается на две половины В и С.
2. Части В и

С сливаются, при этом одиночные элементы из В и С образуют упорядоченные пары.
3. Полученная последовательность А вновь обрабатывается, как указано в двух предыдущих шагах, но сливаются упорядоченные четверки.
4. Повторяя предыдущие шаги, сливаем четверки в восьмерки и т.д., пока не будет упорядочена вся последовательность
Прямое слияниеСортировка, называемая прямым слиянием, выполняется следующим образом:1. Последовательность А разбивается на две половины В и С.2.

Слайд 4Каждый проход (этап) сортировки включает две фазы
Фаза разделения – записи

из файла А разбиваются на две равные части(при нечетном числе

записей в первой части на 1 больше) и помещаются в файлы В и С соответственно

Файл А

Файл В

Файл С

Файл А

Файл В

Файл С

Фаза разделения

Фаза слияния

Фаза слияния – данные из файлов В и С, слитые в упорядоченные пары, четверки, восьмерки и т.д., помещаются в файл А.

Каждый проход (этап) сортировки включает две фазыФаза разделения – записи из файла А разбиваются на две равные

Слайд 5Пример
А:
8
2
13
4
15
6
9
11
3
7
5
10
1
12
14
Фаза разделения
В:
С:
1. Открыть файл А как входной (для чтения)
2. Открыть

файлы В и С как выходные (для записи)
3. Считываемые из

файла А записи попеременно посылаются в файлы В и С

4. Закрыть файлы А, В, С.

ПримерА:821341569113751011214Фаза разделенияВ:С:1. Открыть файл А как входной (для чтения)2. Открыть файлы В и С как выходные

Слайд 6Фаза слияния
А:
8
2
13
4
15
6
9
11
3
7
5
10
1
12
14
В:
С:
1. Открыть файл А как выходной (для записи)
2. Открыть

файлы В и С как входные (для чтения)
3. Установить размер

порции сливаемых записей = 1

Для каждой порции считываются по одной записи из файлов В и С

5. Меньшая из них пересылается в файл А, и считывается очередная запись из того файла, чья запись была переслана в файл А

2 < 8

4 < 8

6 < 8

8<11

11<13

7<13

10<13

12<13

6. Закрыть файлы А, В, С.

Фаза слиянияА:821341569113751011214В:С:1. Открыть файл А как выходной (для записи)2. Открыть файлы В и С как входные

Слайд 7Фаза разделения
1. Открыть файл А как входной (для чтения)
2. Открыть

файлы В и С как выходные (для записи)
3. Считываемые из

файла А записи попеременно посылаются в файлы В и С: первая запись в файл В, вторая в С, затем третья в В, четвертая в С и т.д.
4. Закрыть файлы А, В и С.
Фаза разделения1. Открыть файл А как входной (для чтения)2. Открыть файлы В и С как выходные (для

Слайд 8Фаза слияния
1. Открыть файл А как выходной (для записи)
2. Открыть

файлы В и С как входные (для чтения)
3. Установить размер

порции сливаемых записей (эти порции равны 1, 2, 4, … записям для первого и последующих этапов соответственно).
4. Для каждой порции считываются по одной записи из файлов В и С.
5. Меньшая из них пересылается в файл А, и считывается очередная запись из того файла, чья запись была переслана в файл А.
Фаза слияния1. Открыть файл А как выходной (для записи)2. Открыть файлы В и С как входные (для

Слайд 96. Повторяются пункты 4 и 5 до тех пор, пока

записи очередной одного из файлов не будут исчерпаны.
7. Оставшиеся записи

из порции другого файла пересылаются в файл А.
8. Пункты 4-7 повторяются до тех пор, пока не будет достигнут конец одного из файлов В или С. Тогда оставшиеся записи из другого файла пересылаются в файл А.
9. Закрытие файлов А, В и С.

Сортировка завершается тогда, когда длина порции достигнет n
6. Повторяются пункты 4 и 5 до тех пор, пока записи очередной одного из файлов не будут

Слайд 10Пример двухфазной сортировки прямым слиянием, записи файла – целые числа

(ключи).
//-------------------------------------------
#include
#include
#include
//-------------------------------------------
int main()
{ int vsort1(char* r);
int n,b;

char f[40]="A";
FILE *fin, *fout;
printf("\n Sozdanie file A");
if((fout=fopen(f,"w"))==NULL)
{printf("\n File %s not create",f);
getch();
return -1;
}

Пример двухфазной сортировки прямым слиянием, записи файла – целые числа (ключи).//-------------------------------------------#include #include #include //-------------------------------------------int main(){ int vsort1(char*

Слайд 11 n=100;
printf("\n Ishodhni file\n");
while(n--)
{b=rand(); //заполняем файл

случайными числами
fprintf(fout,"%d ",b);
printf("%d\t",b);
}
fclose(fout);
vsort1(f);

//вызов функции внешней сортировки
printf("\n Otsortirovanni file:\n");
fin=fopen(f,"r");
while(fscanf(fin,"%d",&b)!=EOF)
printf("%d\t",b);
fclose(fin);
getch();
return 0;
}
n=100; printf(

Слайд 12Внешняя двухфазная сортировка прямым слиянием, фаза разделения и вызов фазы

слияния
int vsort1(char *ff) //ff – исходный файл, подлежащий сортировке
{ int vsort2(char

*a, int m); //функция фазы слияния
FILE *A, *B, *C; //файловые переменные
int a; //для чтения из исходного файла
int nb,nc; //счетчики элементов в формируемых группах
int p; //р=1 – признак достижения конеца исходного файла
int m=1; //число элементов в группе: 1,2,4,8,…
int k=0; //счетчик числа элементов в исходном файле
while(1)
{ if ( (A=fopen(ff,"r"))==NULL)
{ printf("\n File %s not open",ff); //Проверка на открытие файла
getch(); return -1; }
if ( (B=fopen("B","w"))==NULL)
{printf("\n File B1 not open");
getch(); return -1; }
if ( (C=fopen("C","w"))==NULL)
{printf("\n File C1 not open");
getch(); return -1; }
Внешняя двухфазная сортировка прямым слиянием, фаза разделения и вызов фазы слиянияint vsort1(char *ff)	//ff – исходный файл, подлежащий

Слайд 13 nb=0; nc=0; p=0;
while(1)
{ while(1)

{ if(fscanf(A,"%d",&a)==EOF)
{ p=1;

break; }
else
{ if(nbдля файла В */
{ fprintf(B,"%d ",a);
k++; nb++;
continue;
}
else
{ fprintf(C,"%d ",a);
k++; nb=0;
nc++;
break;
}
}
}

if(p) break;
while(1)
{ if(fscanf(A,"%d",&a)==EOF)
{ p=1; break; }
else
{ if(ncдля файла С*/
{ fprintf(C, "%d ",a);
k++; nc++;
continue;
}
else
{ fprintf(B, "%d ",a);
k++; nc=0;
nb++; break;
}
}
}

nb=0; nc=0; p=0;  while(1)  { while(1)   { if(fscanf(A,

Слайд 14 if (p) break;
}
fclose(A);
fclose(B);
fclose(C);
vsort2(ff,m); //вызов функции

слияния
if (m>=(k-k/2)) //конец сортировки
{ remove("B");

//удаление вспомогательных файлов
remove("C");
return 0;
}
m=m*2; //увеличиваем число элементов в группе
k=0;
}
}
if (p) break; } fclose(A); fclose(B); fclose(C); vsort2(ff,m);	//вызов функции слияния if (m>=(k-k/2))  //конец сортировки {

Слайд 15vsort2(char *a, int m) /*а – файл для слияния, m –

число элементов в сливаемых группах */
{ FILE *A, *B, *C;

//файловые переменные
int b,c; //для считывания данных из файлов В и С
int nb,nc; //счетчики считанных из групп элементов файлов В и С
int rb,rc; //коды завершения операции считывания из файлов В и С
if((A=fopen(a,"w"))==NULL) //Проверка на открытие файлов
{printf("\n File %s not open",a);
getch(); return -1;
}
if((B=fopen("B","r"))==NULL)
{printf("\n File B not open");
getch(); return -1;
}
if((C=fopen("C","r"))==NULL)
{printf("\n File C not open");
getch(); return -1;
}

Внешняя двухфазная сортировка прямым слиянием, фаза слияния

vsort2(char *a, int m)	/*а – файл для слияния, m – число элементов в сливаемых группах */{ FILE

Слайд 16rb=fscanf(B,"%d",&b); rc=fscanf(C,"%d",&c);
nb=1; nc=1;
while(1)
{ if ((rb>0)&&(rc

С
{ fprintf(A, "%d ",b);
while(fscanf(B,"%d",&b)>0)

fprintf(A,"%d ",b);
fclose(A); fclose(B); fclose(C);
return 0; }
else
{ if ((rb<=0)&&(rc>0)) //конец файла В
{ fprintf(A, "%d ",c);
while(fscanf(C,"%d",&c)>0)
fprintf(A,"%d ",c);
fclose(A); fclose(B); fclose(C);
return 0; }
else
if ((rb<=0)&&(rc<=0)) /*конец обоих файлов В и С случается, если они оба пустые*/
{ fprintf(A, "%d ",c);
fclose(A); fclose(B); fclose(C);
return 0;
} }

Слайд 17 if (nb

fprintf(A, "%d ",b);
rb=fscanf(B,"%d",&b);

nb++; continue; }
else
{ fprintf(A, "%d ",c);
rc=fscanf(C,"%d",&c);
nc++; continue; }
}
if (nb<=m && nc>m)
{ fprintf(A, "%d ",b);
rb=fscanf(B,"%d",&b);
nb++; continue; }
if (nb>m && nc<=m)
{ fprintf(A, "%d ",c);
rc=fscanf(C,"%d",&c);
nc++; continue; }
if (nb>m && nc>m)
{ nb=1; nc=1; continue; }
}
}
if (nb

Слайд 18Однофазная сортировка прямым слиянием
При однофазной сортировке вместо слияния в одну

последовательность результаты слияния сразу же распределяются по двум файлам, которые

станут исходными для следующего прохода. Она требует наличия 4 файлов, по 2 входных и по 2 выходных, при каждом проходе. Такую сортировку также называют двухпутевой сбалансированной сортировкой. Общее число пересылок при однофазной сортировке М=n*log2n.
Однофазная сортировка прямым слияниемПри однофазной сортировке вместо слияния в одну последовательность результаты слияния сразу же распределяются по

Слайд 19Однофазная сортировка прямым слиянием
Файл А
Файл В
Файл С
Файл D
Файл E
Подготовительный этап
Фаза

слияния-разделения
Файл В
Файл С
Файл А
Заключительный этап

Однофазная сортировка прямым слияниемФайл АФайл ВФайл СФайл DФайл EПодготовительный этапФаза слияния-разделенияФайл ВФайл СФайл АЗаключительный этап

Слайд 20//---------------------------------------------
#include
#include
#include
//--------------------------------------------
int main()
{ int vsort1(char* r);
int n,b;

char f[40]="A";
FILE *fin, *fout;
printf("\n Sozdanie file A");
if

((fout=fopen(f,"w"))==NULL)
{ printf("\n File %s not create",f);
getch();
return -1;
}

Пример однофазной сортировки прямым слиянием.

n=100;
printf("\n Ishodni file:\n");
while(n--)
{ b=rand(); /*Заполняем файл случайными целыми числами*/
fprintf(fout, "%d ",b);
printf("%d\t",b);
}
fclose(fout);
vsort1(f);
printf("\n Otsortirovani file:\n");
fin=fopen(f,"r");
while (fscanf(fin,"%d",&b)!=EOF)
printf("%d\t",b);
fclose(fin);
getch(); return 0;
}

//---------------------------------------------#include #include #include //--------------------------------------------int main(){ int vsort1(char* r); int n,b; char f[40]=

Слайд 21int vsort1(char *ff) //ff – исходный файл, подлежащий сортировке
{ int vsort2(char

*f,int k); //функция фазы слияния-разделения
FILE *A, *B, *C; //файловые переменные
int

a; //для чтения из исходного файла
int nb,nc; //счетчики элементов в формируемых группах
int p; //признак достижения конца исходного файла
int m=1; //число элементов в группе: 1,2,4,8…
int k=0; //счетчик числа элементов в исходном файле
while(1)
{ if((A=fopen(ff,"r"))==NULL)
{ printf("\n File %s not open",ff);
getch(); return -1; }
if((B=fopen("B","w"))==NULL)
{ printf("\n File B not open");
getch(); return -1; }
if((C=fopen("C","w"))==NULL)
{ printf("\n File C not open");
getch(); return -1; }

Внешняя однофазная сортировка прямым слиянием, фаза начального разделения и вызов фазы слияния-разделения

int vsort1(char *ff)	//ff – исходный файл, подлежащий сортировке{ int vsort2(char *f,int k);	//функция фазы слияния-разделения FILE *A, *B,

Слайд 22 nb=0; nc=0; p=0;
while(1)
{ while(1)
{ if(fscanf(A,"%d",&a)==EOF)

{ p=1; break;
}
else

{ if(nb { fprintf(B,"%d ",a);
k++; nb++;
continue;
}
else
{ fprintf(C,"%d ",a);
k++; nb=0;
nc++;
break;
}
}
}

if (p) break;
while(1)
{ if (fscanf(A,"%d",&a)==EOF)
{ p=1; break; }
else
{ if(nc { fprintf(C,"%d ",a);
k++; nc++; continue; }
else
{ fprintf(B,"%d ",a);
k++; nc=0;
nb++; break; }
}
}
if(p) break;
}
fclose(A); fclose(B); fclose(C);
vsort2(ff,k); //вызов функции слияния
return 0; m=m*2; k=0;
} }

nb=0; nc=0; p=0; while(1) { while(1) { if(fscanf(A,

Слайд 23vsort2(char *f, int k)
{ FILE *B, *C, *D, *E; //

файловые переменные
int b,c; //для считывания данных

из файлов В и С,
int nb,nc; //счетчики считанных из групп элементов файлов В и С
int nd,ne; //счетчики сливаемых в группы элементов
int rb,rc; //коды завершения операции считывания из файлов В и С
int sm; //число элементов в сливаемой группе: sm=2*m
static m=1; //число элементов в исходной группе
static int p=1; //переключатель
while(1)
{ if (p%2)
{ if((B=fopen("B","r"))==NULL) { printf("\n File B not open");
getch(); return -1; }
if((C=fopen("C","r"))==NULL) {printf("\n File C not open");
getch(); return -1; }
if((D=fopen(f,"w"))==NULL) { printf("\n File D not open");
getch(); return -1; }
if((E=fopen("E","w"))==NULL) { printf("\n File E not open");
getch(); return -1; } }

Внешняя однофазная сортировка прямым слиянием, фаза слияния-разделения

vsort2(char *f, int k){ FILE *B, *C, *D, *E; // файловые переменные int b,c;

Слайд 24else
{ if((B=fopen(f,"r"))==NULL)
{printf("\n File D

not open");
getch();
return

-1;
}
if((C=fopen("E","r"))==NULL)
{printf("\n File E not open");
getch();
return -1;
}
if((D=fopen("B","w"))==NULL)
{printf("\n File B not open");
getch();
return -1;
}
if((E=fopen("C","w"))==NULL)
{printf("\n File C not open");
getch();
return -1;
} }

sm=2*m;
rb=fscanf(B,"%d ",&b);
rc=fscanf(C,"%d ",&c);
nb=1; nc=1; nd=0; ne=0;
while(1)
{ if ((rb>0) && (rc<=0)) /*конец файла С*/
{ if(nd { fprintf(D,"%d ",b);
nd++; }
else
{ fprintf(E,"%d ",b);
ne++; }
while(fscanf(B, "%d", &b)>0)
{ if (nd { fprintf(D, "%d ",b);
nd++; }
else
{ fprintf(E, "%d ",b);
ne++; } }
fclose(B); fclose(C); break; }


Слайд 25 else
{ if ((rb0)) //конец файла

B
{ if (nd

{ fprintf(D, "%d ",c); nd++; }
else
{ fprintf(E, "%d ",c); ne++; }
while(fscanf(C,"%d", &c)>0)
{ if(nd { fprintf(D," %d ",c); nd++; }
else
{ fprintf(E,"%d ",c);
ne++; }
}
fclose(B); fclose(C); break;
}
else
if ((rb<=0) && (rc<=0)) /*конец обоих файлов В и С*/
{ fclose(B); fclose(C); break;
} }

if (nb<=m && nc<=m)
{ if (b<=c)
{ if (nd==sm && ne==sm)
{ nd=0; ne=0; }
if (nd { fprintf(D,"%d ",b);
nd++; }
else
{ fprintf(E,"%d ",b);
ne++; }
rb=fscanf(B,"%d",&b);
nb++; continue; }
else
{ if (nd==sm && ne==sm)
{ nd=0; ne=0; }
if (nd { fprintf(D,"%d ",c); nd++; }
else
{ fprintf(E,"%d ",c); ne++; }
c=fscanf(C,"%d",&c);
nc++; continue; } }

else { if ((rb0))  //конец файла B  { if (nd0)

Слайд 26 if(nb=m)
{ if (nd==sm &&

ne==sm)
{ nd=0; ne=0;

}
if (nd { fprintf(D, "%d ",b);
nd++; }
else
{ fprintf(E, "%d ",b);
ne++; }
rb=fscanf(B,"%d",&b);
nb++; continue; }
if(nb>m && nc<=m)
{ if (nd==sm && ne==sm)
{ nd=0; ne=0; }
if (nd { fprintf(D, "%d ",c);
nd++;
}
else
{ fprintf(E, "%d ",c); ne++; }

rc=fscanf(C,"%d",&c);
nc++; continue;
}
if(nb>m && nc>m)
{ nb=1; nc=1;
continue;
}
} //конец цикла
fclose(B); fclose(C);
fclose(D); fclose(E);
if (m>=(k-k/2))
{ if (!(p%2))
{ remove(f);
rename("B",f);
}
remove("B"); remove("C");
remove("E"); return 0;
}
m=2*m; p=1;
}
}

if(nb=m)   { if (nd==sm && ne==sm)    { nd=0;   ne=0;

Слайд 27Естественное слияние
Сортировка, при которой всегда сливаются две очередные упорядоченные подпоследовательности

(серии), называется естественным слиянием.

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

Слайд 28Процесс естественного слияния на примере. Пусть исходный файл А содержит

записи с ключами:
А:
17
31
5
59
13
41
43
67
11
23
71
29
47
3
7
2
19
57
Выделим серии, которые для наглядности разделим знаками |
Разобьем

файл А на два файла В и С: первую серию запишем в файл В, вторую в файл С, третью в файл В, четвертую в файл С и т.д., которые затем сольем в файл А.

В:

С:

Процесс естественного слияния на примере. Пусть исходный файл А содержит записи с ключами:А:17315591341436711237129473721957Выделим серии, которые для наглядности

Слайд 29Первый проход
А:
17
5
31
59
13
11
41
23
43
29
67
47
3
2
7
В:
С:
5 < 17
71
57
19
17 ≥ 17
5 ≥ 5
Проверка на исчерпанность

текущей серии из файла В
Проверка на исчерпанность текущей серии из

файла С

59 ≥ 5

17 < 59

31 ≥ 17

31 < 59

13 ≥ 31

13 ≥ 13

11 ≥ 11

11 < 13

23 ≥ 11

13 < 23

41 ≥ 13

23 < 41

29 ≥ 23

29 < 41

47 ≥ 29

41 < 47

43 ≥ 41

43 < 47

67 ≥ 43

47 < 67

2 ≥ 47

2 ≥ 2

3 ≥ 3

2 < 3

19 ≥ 2

3 < 19

7 ≥ 3

7 < 19

71 ≥ 7

19 < 71

57 ≥ 19

57 < 71

Конец файла С !

Первый проходА:17531591311412343296747327В:С:5 < 1771571917 ≥ 175 ≥ 5Проверка на исчерпанность текущей серии из файла ВПроверка на исчерпанность

Слайд 30Алгоритм естественного слияния:
1. Открыть файл А как входной (для чтения).
2.

Открыть файлы В и С как выходные (для записи).
3. Считывать

записи и посылать их в файл В до тех пор, пока очередная запись больше предыдущей (ri > ri-1), то есть до конца серии.
4 Запись ri <= ri-1 записать в файл С. Считывать записи и посылать их в С до тех пор, пока ri > ri-1, то есть до конца следующей серии.
5. Выполнять пункты 3 и 4, пока не будет достигнут конец файла А.
6. Выполнить фазу слияния файлов В и С в файл А.
7. Пункты 1-5 повторять до тех пор, пока в результате слияния в выходной файл не будет записана только одна-единственная серия
Алгоритм естественного слияния:1. Открыть файл А как входной (для чтения).2. Открыть файлы В и С как выходные

Слайд 31В процессе сортировки может возникнуть такая ситуация, что несколько серий

из файла А при разделении образуют в выходном файле В

или С одну серию, в таком случае число проходов уменьшается.
Пусть в файле А находятся 6 серий:

А:

1…29

21…47

31…55

49…81

75…80

3…18

При разделении в файлы В и С попадут серии в следующем порядке:

В:

1…29

31…55

75…80

С:

21…47

49…81

3…18

В файле В три серии образовали одну серию

1…80

В файле С первые две серии объединились в одну.

21…81

В процессе сортировки может возникнуть такая ситуация, что несколько серий из файла А при разделении образуют в

Слайд 32Если использовать четыре файла, то фазы слияния и разделения можно

объединить в одну фазу. Для этого достаточно полученные при слиянии

файлов В и С серии поочередно направлять в файлы D и E, и, наоборот, если сливаются серии из файлов D и Е, полученные серии поочередно направлять в В и С.

Сортировка заканчивается, если при очередной фазе слияния-разделения образуется только одна серия и один из выходных файлов останется пустым, т.е. туда не будет записана ни одна серия.
Если использовать четыре файла, то фазы слияния и разделения можно объединить в одну фазу. Для этого достаточно

Слайд 33Пример двухфазной сортировки естественным слиянием
//---------------------------------------------------------------------------
#include
#include
#include
//---------------------------------------------------------------------------
int main()
{ int

vnsort1(char* r); int n,b; char f[40]="A"; FILE

*fin, *fout;
printf("\n Create file A");
if ((fout=fopen(f,"w"))==NULL)
{ printf("\n File %s not create",f); getch(); return -1; }
n=327; printf("\n Ishodni file\n");
while (n--)
{ b=rand(); //заполняем файл случайными числами
fprintf(fout,"%d ",b); printf("%d\t",b); }
fclose(fout);
vnsort1(f); //вызов функции внешней сортировки
printf("\n Otsortirovani file:\n"); fin=fopen(f,"r");
while(fscanf(fin,"%d",&b)!=EOF) printf("%d\t",b);
fclose(fin); getch(); return 0; }
Пример двухфазной сортировки естественным слиянием//---------------------------------------------------------------------------#include #include #include //---------------------------------------------------------------------------int main(){ int vnsort1(char* r);  int n,b;  char

Слайд 34int vnsort1(char *ff) //ff – исходный файл, подлежащий сортировке
{

int vnsort2(char *f); //функция фазы слияния
FILE *A, *B,*C; //

файловые переменные
int a1,a2; //для чтения из исходного файла
int pb,pc; //признаки записи в файлы разделения
int p; //р=1 – признак достижения конеца исходного файла
while(1) //цикл 1 – цикл повторения фаз разделения и слияния
{ if((A=fopen(ff,"r"))==NULL)
{ printf("\n File not open",ff);
getch(); return -1; }
if((B=fopen("B","w"))==NULL)
{ printf("\n File B not open");
getch(); return -1;
}
if((C=fopen("C","w"))==NULL)
{ printf("\n File C not open");
getch(); return -1;
}

Внешняя двухфазная сортировка естественным слиянием, фаза разделения и вызов фазы слияния

int vnsort1(char *ff)  //ff – исходный файл, подлежащий сортировке{ int vnsort2(char *f);	 //функция фазы слияния FILE

Слайд 35 p=0; pb=0; pc=0;

if(fscanf(A,"%d",&a1)==EOF)
{ printf("\nSortiruemi file pustoi");

getch(); return -1; }
else
{ fprintf(B,"%d ",a1); pb=1; }
while(1) //цикл 2, цикл формирования серий в файлах В и С
{ while(1) //цикл 3, цикл формирования серии в файле В
{ if(fscanf(A,"%d",&a2)==EOF)
{ p=1;
break; //выход из цикла 3
}
else
{ if(a2>=a1) //запишем в серию в файле В
{ fprintf(B, "%d ",a2);
a1=a2; pb=1; continue;
}
else //запишем первую запись новой серии в файле С
{ fprintf(C,"%d ",a2);
a1=a2; pc=1;
break; //выход из цикла 3
} } }

Слайд 36 if(p) break; //выход из цикла

2
while(1)

//цикл 4, цикл формирования серии в файле C
{ if(fscanf(A,"%d",&a2)==EOF)
{ p=1;
break; //выход из цикла 4
}
else
{ if(a2>=a1) //запишем в серию в файле C
{ fprintf(C, "%d ",a2);
a1=a2; pc=1; continue; }
else
{ fprintf(B,"%d ",a2);
a1=a2; pb=1;
break; //выход из цикла 4
} } }
if(p) break; //выход из цикла 2
}
fclose(A); fclose(B); fclose(C);
if(pb && pc) vnsort2(ff); //исходный файл записан в оба
else
{ remove("B"); remove("C"); return 0;
} } }

Слайд 37vnsort2(char *a)
{ FILE *A, *B,*C; // файловые переменные
int b1,b2,c1,c2;

//для считывания данных из файлов В и С
int rb,rc; //коды

завершения операции считывания из файлов В и С
// Подготовительные операции
if((A=fopen(a,"w"))==NULL)
{ printf("\n File not open",a);
getch(); return -1;
}
if((B=fopen("B","r"))==NULL)
{ printf("\n File B not open");
getch(); return -1;
}
if((C=fopen("C","r"))==NULL)
{ printf("\n File C not open");
getch(); return -1;
}

Внешняя двухфазная сортировка естественным слиянием, фаза слияния

vnsort2(char *a){ FILE *A, *B,*C; 	// файловые переменные int b1,b2,c1,c2;	 //для считывания данных из файлов В и

Слайд 38rb=fscanf(B,"%d",&b2);
rc=fscanf(C,"%d",&c2);
b1=b2; c1=c2;
while(1)
{ if ((rb>0) && (rc

файла С*/
{ fprintf(A, "%d ",b2);

while(fscanf(B, "%d",&b2)>0)
fprintf(A, "%d ",b2);
fclose(A); fclose(B);
fclose(C); return 0; }
else
{ if ((rb<=0) && (rc>0)) /*конец файла В*/
{ fprintf(A, "%d ",c2);
while(fscanf(C, "%d",&c2)>0)
fprintf(A, "%d ",c2);
fclose(A); fclose(B);
fclose(C); return 0;
} else
if ((rb<=0) && (rc<=0)) /*конец обоих файлов В и С случается , если они оба пустые*/
{ fclose(A); fclose(B);
fclose(C); return 0; } }

Слайд 39 if(b2>=b1 && c2>=c1) //обе сливаемые серии не исчерпаны

{ if(b2

b1=b2; rb=fscanf(B,"%d",&b2); continue; }
else
{ fprintf(A,"%d ",c2); c1=c2; rc=fscanf(C,"%d",&c2); continue; }
}
if(b2>=b1 && c2 { c1=c2; BB:fprintf(A,"%d ",b2); b1=b2; rb=fscanf(B,"%d",&b2);
if(rb<=0) continue;
if(b2>=b1) goto BB; else { b1=b2; continue; }
}
if(b2=c1) //текущая серия из файла В исчерпана
{ b1=b2; CC:fprintf(A,"%d ",c2);
c1=c2; rc=fscanf(C,"%d",&c2);
if(rc<=0) continue;
if(c2>=c1) goto CC;
else
{ c1=c2; continue; }
} } }
if(b2>=b1 && c2>=c1) //обе сливаемые серии не исчерпаны   { if(b2=b1 && c2

Слайд 40Сбалансированное многопутевое слияние
Если в исходном файле имеется п серий и

они поровну распределяются в N файлов, то первый проход даст

n/N серий, второй проход - , третий - и т.д.
Отсюда общее число проходов, необходимых для сортировки п элементов с помощью N-путевого слияния, равно к — logNn, а число пересылок при объединении фаз слияния и разделения в самом худшем случае будет М = nlogNn. При каждом проходе будут участвовать N входных и N. выходных файлов, в которые по очереди распределяются последовательные серии.
Сбалансированное многопутевое слияниеЕсли в исходном файле имеется п серий и они поровну распределяются в N файлов, то

Слайд 41Серия 1
Серия 2
Серия 3
Серия 4
Серия 5
Серия 6
Серия 7
Серия 8
Серия 1
Серия

5
Серия 2
Серия 6
Серия 3
Серия 7
Серия 4
Серия 8
Входной файл
Файл 1
Выходные файлы
Файл

2

Файл 3

Файл 4

Первоначально:

Серия 1Серия 2Серия 3Серия 4Серия 5Серия 6Серия 7Серия 8Серия 1Серия 5Серия 2Серия 6Серия 3Серия 7Серия 4Серия 8Входной

Слайд 42Входной файл может находиться в одном из трех состояний:
1) файл

активен, если не исчерпаны записи текущей j-й серии файла;
2) файл

временно не активен, если исчерпаны записи текущей j-й серии, но не достигнут конец файла. Такой файл не участвует в процессе слияния очередной серии, но активизируется при слиянии следующей серии;
3) файл не активен, если достигнут конец файла, т.е. исчерпаны все серии. В текущем проходе такой файл больше не используется.

Для определения конца текущей серии или конца файла может потребоваться опережающее чтение записи или ведение специальной таблицы.
Входной файл может находиться в одном из трех состояний:1) файл активен, если не исчерпаны записи текущей j-й

Слайд 431
16
Файл 1
Входные файлы
Файл 2
Файл 3
Файл 4
Файл 5
5
3
2
6
9
4
8
12
11
7
10
15
12
14
15
13
18
Файл 6

116 Файл 1Входные файлыФайл 2Файл 3Файл 4Файл 553269481211710151214151318Файл 6

Слайд 44Очередной проход заканчивается, когда будет достигнут конец всех входных файлов.

Выходные файлы становятся входны­ми, а входные файлы - выходными, и

начинается очередной Проход сортировки.
Процесс сортировки заканчивается, когда при очередном проходе будет сформирована одна-единственная серия
Очередной проход заканчивается, когда будет достигнут конец всех входных файлов. Выходные файлы становятся входны­ми, а входные файлы

Слайд 45Многофазная сортировка
Метод многофазной сортировки основан на том, что имеется

несколько входных файлов с разным числом серий и только один

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

Слайд 46Файлы
Исходное состояние
Первый проход
Второй проход
Третий проход
Четвертый проход
Пятый проход
Шестой проход
f1
f2
f3
13
8
0
5
0
8
0
5
3
3
2
0
1
0
2
0
1
1
1
0
0
Пример

ФайлыИсходное состояниеПервый проходВторой проходТретий проходЧетвертый проходПятый проходШестой проходf1f2f31380508053320102011100Пример

Слайд 47Алгоритм слияния эффективно работает на длинных сериях и неэффективно на

коротких. Поэтому его нецелесообразно применять с самого начала сортировки, поскольку

для случайного входного набора на первых шагах будут получаться очень короткие серии, что приведет к неоправданно большому числу обращений к дисковой памяти.
Для устранения этого недостатка можно поступить следующим образом:
исходный сверхбольшой набор данных разделяется на отдельные фрагменты такого размера, чтобы каждый фрагмент мог целиком разместиться в ОП
каждый фрагмент отдельно загружается в ОП и сортируется каким-нибудь классическим улучшенным методом (например – алгоритмом быстрой сортировки)
каждый отсортированный фрагмент рассматривается как серия и сохраняется во вспомогательном файле; в простейшем случае достаточно двух вспомогательных файлов, в которые серии сбрасываются поочередно (нечетные серии – в один файл (A), четные – в другой (B)).
Эти действия носят подготовительный характер.
Алгоритм слияния эффективно работает на длинных сериях и неэффективно на коротких. Поэтому его нецелесообразно применять с самого

Слайд 48Сортировка фрагментов в ОП:
(фрагмент i ) => (серия i )
Фрагмент

1
Фрагмент 2
Фрагмент 3
Фрагмент 4
Фрагмент 5
Фрагмент 6
Серия 1
Файл А
Серия 3
Серия 5
Серия

1

Файл А

Серия 3

Серия 5

Серия 2

Файл В

Серия 4

Серия 6

Сортировка фрагментов в ОП:(фрагмент i ) => (серия i )Фрагмент 1Фрагмент 2Фрагмент 3Фрагмент 4Фрагмент 5Фрагмент 6Серия 1Файл

Слайд 49После этого начинается 2-ой этап сортировки:
выполняется объединение первых серий из

разных файлов, т.е. серий 1 и 2, и результат записывается

в третий вспомогательный файл С
выполняется объединение вторых серий из разных файлов, т.е. серий 3 и 4, и результат записывается во вспомогательный файл D
выполняется объединение третьих серий из разных файлов, т.е. серий 5 и 6, и результат записывается опять в файл С
серии 7 и 8 после объединения записываются в файл D и т.д.
В итоге, в файлах С и D получатся объединенные серии, которые потом между собой начинают попарно объединяться с записью результата во вспомогательные файлы А и В и т. д. Процесс укрупнения серий продолжается до тех пор, пока не будет получена одна единственная серия, представляющая полученный результат.
После этого начинается 2-ой этап сортировки:выполняется объединение первых серий из разных файлов, т.е. серий 1 и 2,

Слайд 50Серия 1
Файл А
Серия 3
Серия 5
Серия 2
Файл В
Серия 4
Серия 6
Серия 1+2
Файл

С
Серия 5+6
Серия 3+4
Файл D
Серия 1+2+3+4
Серия 5+6
Серия
1+2+3+4+5+6
Процесс укрупнения серий

Серия 1Файл АСерия 3Серия 5Серия 2Файл ВСерия 4Серия 6Серия 1+2Файл ССерия 5+6Серия 3+4Файл DСерия 1+2+3+4Серия 5+6Серия 1+2+3+4+5+6Процесс

Обратная связь

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

Email: Нажмите что бы посмотреть 

Что такое TheSlide.ru?

Это сайт презентации, докладов, проектов в PowerPoint. Здесь удобно  хранить и делиться своими презентациями с другими пользователями.


Для правообладателей

Яндекс.Метрика