Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
_МЕТ№2.DOC
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
247.81 Кб
Скачать

3.3. Упорядочение записей в файле

Эта операция выполняется довольно часто. Ее можно выполнить непосредственно в наборе данных, без использования массива записей.

Рассмотрим алгоритм на примере, в котором приведена более общая по сравнению с телефонным справочником структура записей.

Задача.

Набор данных, имя которого задается с клавиатуры, содержит информацию о компьютерах вида:

Марка, Цена.

Упорядочить записи в наборе по возрастанию цены.

Алгоритм

1.1. Ввести имя набора данных

1.2. Связать файл с набором данных

2.1. Признак = "перестановки"

2.2. Пока "перестановки" выполнить

2.2.1. Признак = " нет перестановок"

2.2.2. Номер записи (k) = 0

2.2.3. Открыть файл для чтения

2.2.4. Пока не конец файла выполнить

а) Установить в файле номер записи k

б) Считать из файла Запись1 ( k-ю )

в) Считать из файла Запись2 ( k+1-ю )

г) Если Запись1.Цена > Запись2.Цена то

1) Установить в файле номер записи k

2) Записать в файл Запись2 ( k+1-ю )

3) Записать в файл Запись1 ( k-ю )

4) Признак = "перестановка"

д) k = k + 1

2.2.5. Закрыть файл

3. Закончить.

Программа для этого алгоритма будет иметь следующий вид.

Program Sort_File;

Type

Computer=Record

Marka:String[10];

Cena: Integer;

End;

Var

FilComp:File of Computer;

Comp1,Comp2:Computer;

k:Integer;

Perest:Boolean; { Признак перестановок }

FilName:String;{имя набора данных}

Begin

Writeln('Введите имя набора данных');

Readln(FilName);

Assing(Filan,FilName);

{ Упорядочение }

Perest:=True;{ Перестановки будут }

While Perest do

Begin

Perest:=False;{ Перестановок еще не было }

k:=0;

Reset (FilComp); {открытие файла}

While Not Eof(FilComp) do

Begin

Seek(FilComp,k);

Read(FilComp,Comp1);

Read(FilComp,Comp2);

If Comp1.Cena>Comp2.Cena then

Begin

Seek(FilComp,k);

Write(FilComp,Comp2);

Write(FilComp,Comp1);

Perest:=True;{ Перестановка была }

End;

k:=k+1;

End;

Close(FilComp);

End;

Writeln('Конец работы');

Readln; { Останов }

End.

3.4. Удаление записей из файла

Эта операция может быть 2-х типов:

а) логическое удаление,

б) физическое удаление.

При логическом удалении запись фактически не удаляется. Используется специальный признак: активная/пассивная запись. Логическое удаление – установка признака в состояние "пассивная". При этом запись не стирается. Во время обработки файла проверяется признак и обрабатываются только активные записи.

Пример

В файле ftel некоторые номера телефонов сняты. Для логического удаления необходимо добавить в запись tel еще одно поле, например:

type

tel = record

nom=integer;

fam,Adr:string[15];

Act:Boolean; {признак активная/пассивная (удаления)}

end;

При создании файла ftel поле Act всех записей имеет значение True - запись "активна" (не удалена), т.е. программа при начальном заполнении будет содержать такой фрагмент:

{Начальное заполнение}

Assing (ftel,`tsprav`);

Rewrite (ftel);

With Rtel do

Begin

nom=0;

fam:=``;

Adr:=``;

Act:=True;

end;

For k:=0 to n do

Begin

Seek(ftel,k);

Write(ftel,Rtel);

end;

Удаление записи с номером num выполняется как коррекция (изменяется содержимое поля Act на противоположное):

Writeln(`Введите удаляемый номер телефона');

Read(num);

Seek(ftel,num);

Read(ftel,Rtel);

Rtel.Act:=False;

Seek(ftel,num);

Write(ftel,Rtel);

При обработке файла в этом случае необходима дополнительная проверка наличия (активности) записи:

Seek(ftel,k);

If Not eof(ftel) then

Begin

Read(ftel,Rtel);

if Rtel.Act then {Запись не удалена}

Begin

.....– обработка

end;

......

end;

При физическом удалении записи на ее место переписывается новая информация, т.е. запись стирается. Эта операция выполняется по схеме, приведенной на рис.6., где показано удаление записис с номером 2

Рис. 6. Физическое удаление записи из файла

Составим процедуру удаления записи с заданным номером num из файла f. Нужно учесть, что удаление сводится к переписи записей после номера num на 1 место вперед. После переписи файл нужно закрыть с помощью оператора Close и таким образом убрать из него последнюю запись. Пусть ft=file of tel;

Procedure Removef (num: integer; Var f:ft);

{Удаление записи с номером num из файла f}

Var

k:integer;

Rtel:tel;

Begin

k:=num;

{Перепись записей на 1 вперед - в начало f}

Seek(f,k+1); {следующая запись}

While not eof(f) do

Begin

Read(f,Rtel);

Seek (f,k); {возврат назад ( в начало)}

Write (f,Rtel);

k:=k+1;

Seek (f,k+1);

end;

{Закрываем f перед последней записью}

Seek (f,k-1);

Close (f);

end;

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]