// Отсортировать бинарный файл, содержащий целые числа, в порядке убывания методом естественного слияния.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
/*
** Функция разделения и вызова функции слияния
*/
void SplitFile(char * fileName)
{
FILE * origin, * tempA, * tempB;
int a1, a2, b1, b2; // Для считывания данных
int ra, rb; // Флаги завершения
/* Открываем файлы */
if((origin = fopen(fileName, "wb")) == NULL)
{
printf("Не удалось создать фаил");
return -1;
}
if((tempA = fopen("tempA", "rb")) == NULL)
{
printf("Не удалось открыть фаил");
return -1;
}
if((tempB = fopen("tempB", "rb")) == NULL)
{
printf("Не удалось открыть фаил");
return -1;
}
/* Считываем начальные данные */
ra = fread(&a2, sizeof(int), 1, tempA);
rb = fread(&b2, sizeof(int), 1, tempB);
a1 = a2;
b1 = b2;
while(rb != 0 && ra != 0)
{
/* Обе серии не исчерпаны */
if(a2 <= a1 && b2 <= b1)
{
if(a2 >= b2)
{
fwrite(&a2, sizeof(int), 1, origin);
a1 = a2;
ra = fread(&a2, sizeof(int), 1, tempA);
continue;
}
else
{
fwrite(&b2, sizeof(int), 1, origin);
b1 = b2;
rb = fread(&b2, sizeof(int), 1, tempB);
continue;
}
}
/* Серия из файла tempB исчерпана */
if(a2 <= a1 && b2 > b1)
{
b1 = b2;
while(a2 <= a1)
{
fwrite(&a2, sizeof(int), 1, origin);
a1 = a2;
ra = fread(&a2, sizeof(int), 1, tempA);
if(ra == 0)
break;
}
if(ra == 0)
continue;
a1 = a2;
continue;
}
/* Серия из файла tempA исчерпана */
if(a2 > a1 && b2 <= b1)
{
a1 = a2;
while(b2 <= b1)
{
fwrite(&b2, sizeof(int), 1, origin);
b1 = b2;
rb = fread(&b2, sizeof(int), 1, tempB);
if(rb == 0)
break;
}
if(rb == 0)
continue;
b1 = b2;
continue;
}
}
/* Конец файла tempB */
if((ra > 0) && (rb == 0))
{
/* Записываем ранее считанное значение */
fwrite(&a2, sizeof(int), 1, origin);
/* Считали с tempB и записали в оригинальный фаил */
while(fread(&a2, sizeof(int), 1, tempA))
fwrite(&a2, sizeof(int), 1, origin);
}
/* Конец файла tempA */
if((ra == 0) && (rb > 0))
{
/* Записываем ранее считанное значение */
fwrite(&b2, sizeof(int), 1, origin);
/* Считали с tempB и записали в оригинальный фаил */
while(fread(&b2, sizeof(int), 1, tempB))
fwrite(&b2, sizeof(int), 1, origin);
}
fclose(origin);
fclose(tempA);
fclose(tempB);
return 0;
}
/*
** Функция разделения и вызова функции слияния
*/
int SortFile(char * fileName)
{
FILE * origin, * tempA, * tempB;
int a1, a2; // для чтения из исходного файли
int pb , pc; // для записи в файлы разделения
int p; // признак достижения конца файла
do
{
/* Открываем файлы */
if((origin = fopen(fileName, "rb")) == NULL)
{
printf("Не удалось открыть фаил");
return -1;
}
if((tempA = fopen("tempA", "wb")) == NULL)
{
printf("Не удалось создать фаил");
return -1;
}
if((tempB = fopen("tempB", "wb")) == NULL)
{
printf("Не удалось создать фаил");
return -1;
}
p = pb = pc = 0;
/* Проверка если не пустой */
if(fread(&a1, sizeof(int), 1, origin))
{
fwrite(&a1, sizeof(int), 1, tempA);
pb = 1;
}
else
return -1;
/* Формируем серии в файле tempA и tempB */
while(!p)
{
p = 1;
/* Формируем серии в файле tempA*/
while(fread(&a2, sizeof(int), 1, origin))
{
p = 0;
if(a2 <= a1)
{
fwrite(&a2, sizeof(int), 1, tempA);
a1 = a2;
pb = 1;
continue;
}
else
{
/* Запишем запись для tempB */
fwrite(&a2, sizeof(int), 1, tempB);
a1 = a2;
pc = 1;
break;
}
}
if(p) break;
/* Формирование серий для tempB */
while(fread(&a2, sizeof(int), 1, origin))
{
if(a2 <= a1)
{
fwrite(&a2, sizeof(int), 1, tempB);
a1 = a2;
pc = 1;
continue;
}
else
{
fwrite(&a2, sizeof(int), 1, tempA);
a1 = a2;
pb = 1;
break;
}
}
}
fclose(origin);
fclose(tempA);
fclose(tempB);
/* Если исходный файли записан в оба файла */
if(pb && pc)
SplitFile(fileName);
}while(pb && pc);
remove("tempA");
remove("tempB");
return 0;
}
int main()
{
int N , temp;
char fileName[] = "file";
FILE * fIn, * fOut;
/* Создаем фаил */
if((fIn = fopen(fileName, "wb")) == NULL)
{
printf("Не удалось создать фаил");
return -1;
}
srand(time(0));
N = rand()%100;
printf("Фаил в неотсортированном виде \n");
while(N--)
{
temp = rand()%1000-500;
fwrite(&temp, 1, sizeof(int), fIn);
printf("%d ", temp);
}
printf("\n\n");
fclose(fIn);
/* Функция сортировки */
SortFile(fileName);
/* Отсортированный файли */
if((fOut = fopen(fileName, "rb")) == NULL)
{
printf("Не удалось открыть фаил");
return -1;
}
printf("Фаил в отсортированном виде \n");
while(fread(&temp, 1, sizeof(int), fOut))
printf("%d ", temp);
printf("\n\n");
fclose(fOut);
return 0;
}