Пример программы работы с файлом данных.
Сортировка таблицы адресов (индексная сортировка)
Объем данных, помещенных в каждую из записей файла, может
быть столь большим, что при сортировке перемещение самих записей
является нецелесообразным из-за больших накладных расходов.(рис.1)
а – файл до сортировки, б – файл после сортировки.
При индексной сортировке создается вспомогательная таблица указателей (файл) на записи файла данных(информационного). Вместо перемещения записей в информационном файле перемещаются указатели в индексном файле.
Этот метод называется сортировкой таблицы адресов(индексная сортировка).
Таким образом, сортировке подвергается не сам информационный файл, а вспомогательный файл, каждая запись которого состоит из поля указателя на запись информационного файла и поля ключа этой записи.
Рис.2
Первоначально элемент в позиции j индексного файла указывает на j-ю запись. После окончания сортировки первый указатель указывает на запись файла с наименьшим ключом. Второй указатель - на запись файла со следующим по порядку сортировки ключом и т.д.
Сортировку таблицы указателей можно выполнять одним из методов внутренней сортировки.
Преимущество – скорость;
недостаток – дополнительная память для хранения индексного файла.
Пусть каждая запись файла данных содержит два поля: табельный номер
сотрудника и его Ф.И.О. Требуется добавлять, удалять и просматривать
файл данных. После каждой операции добавления записи в файл необходимо его записи сортировать в порядке увеличения табельного номера. При этом сортировка записей должна производится с помощью
индекса.
Особенности алгоритма:
1. Удаление реализуем таким образом, что на место удаляемой записи переписываем следующую и т.д., а последнюю запись отсекаем.
2. Сортируем информацию в ОЗУ для чего индексный файл считываем в ОЗУ, сортируем и записываем вновь.
3. Информационный файл Data.dat, индексный файл Index.dat
{ Программа является примером работы с индексными файлами }
Program Index;
Uses Dos,Crt;
Const
M = 5; число пунктов меню
Type
Ft = Record
Tn: Word; структура записи информационного файла
Fio: String
End;
It = Record
Tn: Word; структура записи индексного файла
Pos: Word
End;
Var
DataF: File Of Ft;
IndexF: File Of It;
bCase: Byte;
X:Array[1..4096] of It; - рабочий массив
Procedure Browse; (3)
{ Процедура выводит на экран записи из файла Data.Dat
в порядке храниения на диске (без использования Index.Dat)}
Var
VarDF:Ft;
wI:Word;
Begin
Writeln('Номер записи Таб.номер Фамилия И.О.');
Writeln;
wI:=1;
Seek(DataF,0);
While Not(Eof(DataF)) Do Begin
Read(DataF,VarDF);
With VarDF Do позволяет работать с именами полей как с
обычными переменными, т.е без указания перед
идентификаторм поля имени переменной,
определяющей запись
Writeln(wI:5,' ',Tn,' ',Fio);
wI:=wI+1;
End;
End;
Procedure BrowseI; (4)
{ Процедура выводит на экран записи из файла Data.Dat
с использованием Index.Dat}
Var
VarDF:Ft;
VarIF:It;
wI:Word;
Begin
Writeln('Номер записи Таб.номер Фамилия И.О.');
Writeln;
Seek(IndexF,0);
While Not(Eof(IndexF)) Do Begin
Read(IndexF,VarIF);
Seek(DataF,VarIF.Pos-1); потому, что записи нумеруются с 0
Read(DataF,VarDF);
wI:=VarIF.Pos;
With VarDF Do
Writeln(wI:5,' ',Tn,' ',Fio);
End;
End;
Procedure Reindex;
{ Процедура пересоздает файл Index.Dat }
{ Алгоритм:
Считываем табельный номер из Data.Dat в массив X,
сортируем массив методом пузырька и записываем результат
в Index.Dat
}
Var
VarDF:Ft;
VarIF:It;
Wf,wI,wJ:Word;
Begin
{ Очищаем IndexF }
Rewrite(IndexF);
{ Заполняем массив X }
Wf := FileSize(DataF);
wI:=1;
Seek(DataF,0);
While Not(Eof(DataF)) Do Begin
Read(DataF,VarDF);
X[wI].Tn := VarDF.Tn;
X[wI].Pos := wI;
wI := wI+1;
End;
{ Сортируем X }
If Wf > 1 Then Begin
For wI:=1 To Wf-1 Do Begin
For wJ:=1 To Wf-wI Do Begin
If X[wJ+1].Tn < X[wJ].Tn Then Begin
VarIF:=X[wJ+1];
X[wJ+1]:=X[wJ];
X[wJ]:=VarIF;
End;
End;
End;
End;
{ Теперь записываем получившийся массив в Index.Dat }
For wI:=1 To Wf Do Begin
Write(IndexF,X[wI]);
End;
End;
Procedure Append; (1)
{ Процедура добавляет запись в файл Data.Dat }
Var
VarDF:Ft;
Begin
ClrScr;
Write('Табельный номер:');
Readln(VarDF.Tn);
Write('Фамилия:');
Readln(VarDF.Fio);
Seek(DataF,FileSize(DataF));
Write(DataF,VarDF);
Reindex;
Writeln;
Write('Запись добавлена. Нажмите <Enter>...');
Readln;
End;
Procedure Delete; (2)
{ Процедура удаляет запись из файла Data.Dat }
Var
Old,Curr:Ft;
Wz, wI:Word;
Begin
ClrScr;
Browse;
Writeln;
Write('Введите номер удаляемой записи:');
Readln(Wz);
If (Wz<1) Or (Wz>FileSize(DataF)) Then Begin
Writeln;
Writeln('Нет записи с таким номером. Нажмите <Enter>...');
Readln;
End
Else Begin
Old.Tn := 0;
Old.Fio := '';
For wI:=FileSize(DataF) Downto Wz Do Begin
Seek(DataF,wI-1);
Read(DataF,Curr);
Seek(DataF,wI-1);
Write(DataF,Old);
Old:=Curr;
End;
Seek(DataF,FileSize(DataF)-1);
Truncate(DataF);
Reindex;
Writeln;
Write('Запись удалена. Нажмите <Enter>...');
Readln;
End;
End;
Begin
Assign(DataF,'Data.Dat');
Assign(IndexF,'Index.Dat');
{$I-}
Reset(DataF);
{I+}
If IOResult<>0 Then Rewrite(DataF);
{$I-}
Reset(IndexF);
{I+}
If IOResult<>0 Then Rewrite(IndexF);
{ Меню }
bCase := 0;
Repeat
ClrScr;
Writeln('1. Добавить запись в файл');
Writeln('2. Удалить запись из файла');
Writeln('3. Просмотреть файл без использования индекса');
Writeln('4. Просмотреть файл с использованием индекса');
Writeln('5. Выход');
Writeln;
Write('Номер пункта:');
ReadLn(bCase);
Case bCase Of
1:Append;
2:Delete;
3:Begin
ClrScr;
Browse;
Writeln;
Write('Просмотр закончен. Нажмите <Enter>...');
Readln;
End;
4:Begin
ClrScr;
BrowseI;
Writeln;
Write('Просмотр закончен. Нажмите <Enter>...');
Readln;
End;
End;
Until bCase = M;
End.
Пример.
Data.dat
Попов | |
Сидоров | |
Петров | |
Иванов |
x[1] = 25,1
x[2] = 13,2
x[3] = 11,3
x[4] = 36,4
x[1] = 11,3
x[2] = 13,2
x[3] = 25,1
x[4] = 36,4
Index.dat
11,3
13,2
25,1
36,4
Внешняя сортировка
Внешняя сортировка, как правило производится для наборов данных,
хранящихся на ВЗУ в файлах. Эти наборы данных не помещаются це-
ликом в оперативной памяти.
Для выполнения внешней сортировки производятся следующие операции:
1. Находятся во внешней памяти нужные записи для сравнения их ключей.
2. Производится считывание данныз в ОЗУ.
3. В ОЗУ осуществляются операции сравнения и перестановки, т.е.
ссортировка.
4. Выполняется запись во внешнюю память в соответствии с 1 и 3.
При выборе алгоритма сортровки необходимо учитывать следующие
параметры:
- объем ОЗУ, используемой в качестве рабочей области
- объем внешней памяти, используемой в качестве рабочей области
- число записей и их длину
- время выполнения операций в ОЗУ.
Наиболее общей формой внешней сортировки является сортировка слия-
нием. Процесс внешней сортировки состоит из 2-х этапов:
- этап сортировки
- этап сляиния.
Пусть весь исходный набор данных первоначально размещен в одном
месте (массиве НБ3).
НБ3
-----------------------------------------
| 5 6 1 3 2 8 7 11 10 12 4 9 13 16 15 14|
-----------------------------------------
Этот набор данных разбивается на два НБ1 и НБ2, например нечетные
записи переписываются в НБ1, а четные в НБ2 (рис.)
Сортировка производится в два этапа:
1) из записей, которые хранятся в каждом из наборов данных с помощью
внутренней сортировки формируются упорядоченные цепочки записей.
Длина цепочек L такая, чтобы все записи размещались в ОП. Пусть
L=2, т.е. в ОП размещается только 2 логических записи. В резуль-
тате 1- го этапа в наборах данных будут размещенгы упорядоченные
цепочки по две записи. Здесь может быть использован любой метод
внутренней сортировки.
НБ3 НБ4
|1 5 | 2 7 | 4 10 | 13 15| |3 6| 8 11 | 9 12 | 14 16|
L
2)Слияние полученных наборов. Слияние происходит в несколько циклов.
После каждого цикла длина цепочки увеличивается.
После 1-го цикла
НБ1 НБ2
| 1 3 5 6 | 4 9 10 12| | 2 7 8 11 | 13 14 15 16 |
2L
После 2-го цикла
НБ3 НБ4
| 1 2 3 5 6 7 8 11 | | 4 9 10 12 13 14 15 16 |
4 L
После последнего слияния
НБ1
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |