Имя
переменной
|
Тип
переменной
|
Адрес
в памяти
|
Размер
(Б)
|
Назначение
переменной
|
Модуль
UnitMain.pas
|
NPO
|
TNPO
|
$B921F0
|
4
|
Ссылка
на объект - НПО
|
Модуль
UnitSearch.pas
|
M
|
TLevel1
|
$12F1E8
|
25
|
Переменная-буфер
для хранения инф. о найденном в структуре договоре
|
Модуль
UnitCorrect.pas
|
P
|
PLevel1
|
$12F814
|
4
|
Указатель
на корректируемую запись в структуре
|
Модуль
Structures.pas
|
Head
|
PLevel1
|
$BBDDD4
|
4
|
Указатель
на первый элемент в первом уровне списка
|
Current
|
PLevel1
|
$BBDDD8
|
4
|
Текущий
указатель в первом уровне
|
Count
|
Word
|
$BBDDDC
|
2
|
Количество
элементов в списке на первом уровне
|
I
|
Byte
|
$12FC2C
|
1
|
Переменная
для организации циклов
|
J
|
Byte
|
$12FC2B
|
1
|
Переменная
для организации циклов
|
NewNode
|
PLevel1
|
$12F1EC
|
4
|
Временный
буфер для хранения добавляемого в список элемента
|
CurC
|
PLevel2
|
$12FC44
|
4
|
Текущий
указатель в списке второго уровня
|
CurN
|
PLevel3
|
$12FC40
|
4
|
Текущий
указатель в списке третьего уровня
|
NewL2
|
PLevel2
|
$12FBFC
|
4
|
Временный
буфер для хранения добавляемого на второй уровень элемента
|
NewL3
|
PLevel3
|
$12FBE8
|
4
|
Временный
буфер для хранения добавляемого на третий уровень элемента
|
Модуль
Organizations.pas
|
XD
|
Array[1..50] of TXDogovor
|
$B6AF34
|
4000
|
Массив
для хранения информации о всех договорах
|
WTK
|
Array[1..30] of TMemWTK
|
$B6BED4
|
3480
|
Массив
для хранения информации о всех исполнителях
|
Bank
|
Array[1..20] of TBank
|
$B6CC6C
|
1360
|
Массив
для хранения информации о всех отделениях банка
|
XDCount
|
Integer
|
$B6D1BC
|
4
|
Число
жильцов
|
WTKCount
|
Integer
|
$B6D1C0
|
4
|
Число
главных квартиросъёмщиков
|
BankCount
|
Integer
|
$B6D1C4
|
4
|
Число
квартир
|
Struct
|
THiearchList
|
$B6D1D4
|
4
|
Ссылка
на объект (трёхуровневый иерархический список)
|
XDTable
|
TStringGrid
|
$B6D1C8
|
4
|
Указатель
на TStringGrid,
в котроый выводися информация о договорах
|
WTKTable
|
TStringGrid
|
$B6D1CC
|
4
|
Указатель
на TStringGrid,
в котроый выводися информация о исполнителях
|
BankTable
|
TStringGrid
|
$B6D1D0
|
4
|
Указатель
на TStringGrid,
в котроый выводися информ. об отделениях банка
|
I
|
Byte
|
$12FB1E
|
1
|
Переменная
для организации циклов
|
J
|
Byte
|
$12FB1D
|
1
|
Переменная
для организации циклов
|
K
|
Byte
|
$12FB1E
|
1
|
Переменная
для организации циклов
|
Логическая
структура данных
В данном курсовом проекте базовой структурой
данных является трёхуровневый иерархический список (hierarchical
list). В такой структуре каждый элемент (узел) состоит из информационных полей,
указателя на список второго уровня и поля для размещения единственного
структурного указателя. Элемент второго уровня иерархии содержит информационные
поля, указатель на список третьего уровня иерархии и структурный указатель на
следующий элемент во втором уровне. Элемент третьего уровня содержит
информационное поле и указатель на следующий элемент в третьем уровне иерархии.
В нашем случае информационными полями являются данные о договоре, городах и
счетах банка.
//Запись - элемент первого уровня иерархии
TLevel1 = Record
Number : Word;
//Номерхоздоговора
StartDate:
String[10];
//Датазаключения: Boolean; //Признак завершения: Word; //Цена работ по
договору: PLevel2; //Указатель на второй уровень иерархии: PLevel1 //Указатель
на следующий элемент;
//Запись - элемент второго уровня иерархии
TLevel2 = Record
City : String[20];
//Названиегорода: PLevel3; //Указатель на третий уровень иерархии: PLevel2
//Указатель на следующий элемент;
//Запись - элемент третьего уровня иерархии
TLevel3 = Record
Account:
LongWord; //Номеррасчётногосчёта:
PLevel3 //Указатель на следующий элемент;
Поле логического указателя элементов всех
уровней хранит адрес в памяти следующего элемента списка. Пользуясь указателем,
можно получить доступ к элементу списка, а от него к следующему элементу и т.
д., пока не будет достигнут последний элемент.Поле указателя последнего
элемента списка должно содержать признак пустого указателя (NIL),
свидетельствующий о конце списка. Логическая структура трёхуровневого
иерархического списка представлена ниже:
Схема
Логические схемы операций в базовой
структуре данных
Как уже было сказано выше, данный курсовой
проект посвящен освоению работы с трёхуровневым иерархическим списком, его
формированию, а также организации основных операций обработки. Ниже рассмотрим
более детально основные операции и методы их реализации, а также алгоритм
сортировки прямым выбором.
Формирование.
Процесс формирования происходит с помощью
операции добавления нового элемента в конец уже имеющегося списка. Операция
добавления элемента в трёхуровневый иерархический список требует задания всех
нужных информационных полей, а также информации о втором и третьем уровне. В
данном проекте это информация передаётся в виде массивов.
//Добавление члена ВТК в иерархический список
procedure THierarchList.Add(S:
String; D: Boolean; N, P: Word;City: TCities; Cnt: Byte; var Accounts:
TAccounts);: PLevel1;, NewL2: PLevel2;, NewL3: PLevel3;, J: Byte;
begin(NewNode); //Выделяем память под узел
первого уровня
with NewNode^ do:= NIL; //Заполняемполяпервогоуровня:=
S;:= N;:= P;:= D;:= NIL;I := 1 To Cnt do //Начинаемзаполнятьвторойуровень
New(NewL2);
//Выделяемпамятьподузелвторогоуровня(Cities = NIL) //Вставляем его во второй
уровень
then Cities := NewL2CurC^.Next :=
NewL2;
NewL2^.City := City[I]; //Заполняем поле
(город)^.Next := NIL; //Указатель на следущий - NIL^.Accounts := NIL;
//Начинаем заполнять третий уровень
For J := 2 to Accounts[I, 1] do
begin(NewL3); //Выделяем память под узел
третьего уровня
NewL3^.Account := Accounts[I, J];//Заполняемполе
(счёт)
NewL3^.Next := NIL; //Указатель на следущий -
NIL(NewL2^.Accounts = NIL) //Вставляем его на третий уровень
then NewL2^.Accounts :=
NewL3CurN^.Next := NewL3;:= NewL3;:= NewL2
end;(Current = NIL) //Помещаем узел первого
уровня в наш список
then Head := NewNodeCurrent^.Next :=
NewNode;
Current := NewNode;(Count) //Увеличиваем
количество элементов в списке
Просмотр трёхуровневого иерархического списка
Процедура просмотра трёхуровневого
иерархического списка связана с выполнением над каждым элементом каждого уровня
одной и той же операции. Просмотр списка начинается с его головы (Head)
и длиться, пока структурный указатель натекущий элемент (Current)
не будет равным NIL.
Это означает, что предыдущий элемент был последним в списке и просмотр
закончен. Просмотр второго и третьего уровня осуществляется аналогично во
вложенных циклах. В качестве примера представлена процедура печати
информационных полей иерархической структуры в компонент TStringGrid:
//Вывод структуры на форму в StringGrid
procedure THierarchList.Show(SG:
TStringGrid);, J, L: Byte;: PLevel2;: PLevel3;I := 1 to 30 do //Чистим
StringGridJ := 0 to 10 do.Cells[J,I] := '';:= 1;:= Head;I := 1 to Count do
//Проход по первому уровню.Cells[0, L] := IntToStr(Current^.Number);//Выводим
поля первого уровня.Cells[1, L] :=
Current^.StartDate;(Current^.Done)SG.Cells[2, L] := 'Завершён'.Cells[2, L] := 'Незавершён';.Cells[3,L]
:= IntToStr(Current^.Price); := Current^.Cities;//Начинаем
просматривать второй уровень структуры
While (CurC<>NIL)
do
begin
SG.Cells[4,L]
:= CurC^.City;
//Выводим поле узла второго уровня (город)
CurN := CurC^.Accounts;
//И начинаем просматривать третий уровень
While (CurN<>NIL)
do
begin
//Выводим поле третьего уровня (счёт)
SG.Cells[5,L] := SG.Cells[5,L] +
IntToStr(CurN^.Account) + ', '; := CurN^.Next//И
движемся дальше по третьему уровню
end;
Inc(L);
CurC := CurC^.Next//Здесь
движемся дальше по второму уровню
end;:= Current^.Next //А здесь по
первому...;
Сортировка прямым выбором
Сортировка с помощью прямого выбора основана на
следующем алгоритме:
· выбираем (выделяем) элемент с
наименьшим (среди всех N
элементов) ключом;
· элемент с наименьшим ключом меняется
местами с первым элементом.
· Затем выбираем элемент с наименьшим
ключом среди всех элементов, кроме первого элемента; меняем его местами со
вторым элементом и т. д.
Эти операции затем повторяются с оставшимися N2
элементами, затем с N3
элементами, пока не останется только один элемент наибольший.
Реализация этого алгоритма в трёхуровневой
иерархической структуре приведена ниже:
//Cортировка прямым выбором по возрастанию
procedureTHierarchList.SortingUp;
var, J: Word;: PLevel1;:= Head;I :=
1 to Count-1 do:= Min^.Next;J := 1 to Count - I do
begin //Сравниваем текущий элемент с первым
неупорядоченным
if (Min^.Price > Current^.Price)
then
Swap(Min, Current); //Меняем их местами если
надо:= Current^.Next //И движемся дальше по списку
end;
Min := Min^.Next
end
Руководство пользователя
Исполняемым файлом данного курсового проекта
является файл «KursWork.exe»,
после запуска которого на экране появляется главное окно приложения:
Рис.
Управление программой происходит с помощью
главного меню и кнопок. Пункт меню Файл содержит 2 пункта:
Рис.
Открыть - открытие подготовленных файлов с
данными о хоз. договорах, исполнителях и отделениях банка. При этом вся
информация с файла загрузится в таблицы класса TNPO
и на экран.
Выход - завершить работу с приложением.
Пункт меню О программе вызывает небольшое
диалоговое окно, показывающее краткую информацию о проекте:
Рис.
После того, как будут открыты информационные
файлы, станет доступной кнопка на вкладке «3-ёх уровневая иерархия»:
Сформировать.
Рис.
По нажатию на эту кнопку происходит формирование
трёхуровневого иерархического списка и отображение его на экране. Также после
этого станут доступны Несколько других кнопок. Корректировка - изменение
информационных полей в узлах первого уровня иерархического спика. При этом
появиться следующее окно редактирования:
Рис.
Поиск - поиск в трёхуровневом иерархическом
списке договора по его номеру. Форма для поиска будет иметь такой вид:
Рис.
Сортировка - сортировка трёхуровневого
иерархического списка прямым выбором по стоимости услуг. Сортировка может
производиться как по возрастанию, так и по убыванию. Сразу после сортировки
содержимое таблицы на экране обновится.
Заключение
Была изучена и реализована логическая структура
трёхуровневого иерархического списка. Кроме того, был реализован механизм ввода
всей информации с внешнего накопителя (файлыXD.dat,
WTK.dat,
Bank.dat).
Наконец, был рассмотрен метод сортировки прямым выбором, тестирование которой
показало положительные результаты при работе с различными исходными данными.
Разработанная в ходе курсового проектирования
программа удовлетворяет следующим, предусмотренным заданием, требованиям:
. реализованы операции формирования,
просмотра, добавления, корректировки, сортировки и поиска в трёхуровневой
иерархической структуре;
. программа обеспечивает возможность
просматривать упорядоченный список как по возрастанию, так и по убыванию
требуемого ключа.
. Трёхуровневый иерархический список
реализован в отдельном классе (THirarchList).
Литература
.Бакнелл
Д.М. Фундаментальные алгоритмы и структуры данных в Delphi. СПб: ООО
«ДиаСофтЮП», 2003. 506 с.
.Вирт
Н. Алгоритмы и структуры данных. СПб: Невский диалект, 2001. - 352 с.
.Альфред
В. Ахо и др. Структуры данных и алгоритмы. - М.: Вильямс, 2001.
.Р.
Л. Структуры данных и проектирование программ. - М.: БИНОМ. Лаборатория знаний,
2008. - 765 с.
Приложение
(Исходные тексты всех модулей)
МодульUnitMain.
unit
UnitMain;
interface, Messages, SysUtils,
Variants, Classes, Graphics, Controls, Forms,, Grids, ComCtrls, Menus,
Organizations, StdCtrls, XPMan,, UnitCorrect;= class(TForm): TPageControl;:
TMainMenu;: TTabSheet;: TTabSheet;: TTabSheet;: TStringGrid;: TStringGrid;:
TStringGrid;: TMenuItem;: TMenuItem;: TMenuItem;: TMenuItem;: TMenuItem;:
TMenuItem;: TMenuItem;: TMenuItem;: TOpenDialog;: TTabSheet;: TStringGrid;:
TXPManifest;: TButton;: TButton;: TButton;: TButton;:
TButton;FormCreate(Sender: TObject);N4Click(Sender: TObject);N9Click(Sender:
TObject);N5Click(Sender: TObject);N6Click(Sender: TObject);N7Click(Sender:
TObject);Button1Click(Sender: TObject);Button3Click(Sender: TObject);Button4Click(Sender:
TObject);Button2Click(Sender: TObject);Button5Click(Sender: TObject);:
TNPO;;Main: TMain;
{$R *.dfm}
//ЗаполняемшапкитаблицисоздаёмНПОTMain.FormCreate(Sender:
TObject);StringGrid1 do[0,0] := ' № дог.';[1,0] := ' Дата
закл.';
Cells[2,0] := '
Дата зав.';
Cells[3,0] := '
Тема';
Cells[4,0] := '
Организация';
Cells[5,0] := '
Признак';
Cells[6,0] := '
Стоимость'
end;StringGrid2 do[0,0] := '
Фамилия';[1,0] := ' Имя';[2,0] := ' Отчество';[3,0] := ' Год рожд';[4,0] := '
Код XD';[5,0] := ' Признак';[6,0] := ' Сумма';[7,0] := ' Адрес';[8,0] := '
Банк';[9,0] := ' Счет';StringGrid3 do[0,0] := ' № отделения';[1,0] := ' Город';[2,0]
:= ' Адрес отделения';
Cells[3,0] := '
Наимен. отделения';
Cells[4,0] := '
Код отделения'
end;
with StringGrid4 do[0,0] := '
Номер';[1,0]
:= ' Дата закл.';
Cells[2,0] := '
Признак';
Cells[3,0] := '
Стоимость';
Cells[4,0] := '
Города';
Cells[5,0] := '
Счета'
end;:= TNPO.Create(StringGrid1,
StringGrid2, StringGrid3);
//Пункт меню
"Выход"TMain.N4Click(Sender: TObject);
Close
end;
//Пункт меню "О программе"
procedure TMain.N9Click(Sender:
TObject);(Handle, PChar('Курсовой проект' + #13 + 'ст. гр. 107218 Горбачёв П.
И.'),
'Информация', MB_ICONINFORMATION);
//Пункт
меню
"Открыть
файл
ХозДоговоры"TMain.N5Click(Sender:
TObject);OpenDialog1.Execute then.LoadXD(OpenDialog1.FileName);.ShowXD;
//Пункт меню "Открыть файл
Исполнители"
procedure TMain.N6Click(Sender:
TObject);OpenDialog1.Execute then.LoadWTK(OpenDialog1.FileName);.ShowWTK;
//Пункт меню "Открыть файл Отделения
Банков"
procedure TMain.N7Click(Sender:
TObject);OpenDialog1.Execute then.LoadBank(OpenDialog1.FileName);.ShowBank;
//Сформировать
списокTMain.Button1Click(Sender: TObject);((NPO.CountXD = 0) or (NPO.CountWTK =
0) or (NPO.CountBank = 0)) then(Handle, 'Не хватате данных', 'Ошибка',
MB_ICONERROR);
end;
//Создём список и выводим его
NPO.CreateList;.Struct.Show(StringGrid4);.Enabled
:= False;.Enabled := True;.Enabled := True;.Enabled := True;5.Enabled
:= True;
end;
//Кнопка "Сортировать по возрастанию"
procedure TMain.Button3Click(Sender:
TObject);.Struct.SortingUp; //Сортируем иерархический
список.Struct.Show(StringGrid4) //и выводим;
//Кнопка "Сортировать по убыванию"
procedure TMain.Button4Click(Sender:
TObject);.Struct.SortingDown; //Сортируем иерархический список.Struct.Show(StringGrid4)
//и выводим;
//Кнопка
"Поиск"TMain.Button2Click(Sender: TObject);.ShowModal;
//Кнопка
"Корректировать"TMain.Button5Click(Sender:
TObject);.ShowModal;.Struct.Show(StringGrid4);.
МодульUnitSearch.UnitSearch;,
Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,, StdCtrls,
Grids, Structures;= class(TForm): TStringGrid;: TLabel;:
TEdit;FormCreate(Sender: TObject);Edit1Change(Sender:
TObject);Edit1KeyPress(Sender: TObject; var Key: Char);;Search: TSearch;
{$R *.dfm}UnitMain;TSearch.FormCreate(Sender:
TObject);StringGrid1 do[0,0] := ' Номер';[1,0] := ' Дата
закл.';
Cells[2,0] := '
Признак';
Cells[3,0] := '
Стоимость';
end;;
//Поиск договоровTSearch.Edit1Change(Sender:
TObject);: TLevel1;:=
Main.NPO.Struct.SearchByNumber(StrToInt(Edit1.Text));//Ищем договор1
do
begin //И выводим
информацию о найденном договоре
Cells[0,1] :=
IntToStr(M.Number);[1,1] := M.StartDate;(M.Done)Cells[2,1] :=
'Завершён'Cells[2,1] := 'Не завершён';[3,1] := IntToStr(M.Price);
end;
//Ограничение на ввод букв
procedure
TSearch.Edit1KeyPress(Sender: TObject; var Key: Char);Not(Key in ['0'..'9',
#8]) then Key := #0;.
МодульUnitCorrect.UnitCorrect;,
Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,, StdCtrls,
Structures;= class(TForm): TLabel;: TEdit;: TLabel;: TLabel;: TLabel;: TEdit;:
TEdit;: TEdit;: TLabel;: TEdit;: TButton;: TButton;Button2Click(Sender:
TObject);Edit1KeyPress(Sender: TObject; var Key: Char);Edit1Change(Sender:
TObject);Button1Click(Sender: TObject);FormShow(Sender: TObject);;Correct:
TCorrect;
{$R *.dfm}UnitMain;P: PLevel1;
//Кнопка
"Отмена"TCorrect.Button2Click(Sender: TObject);
Close
end;
//Ограничение на ввод букв
procedure
TCorrect.Edit1KeyPress(Sender: TObject; var Key: Char);Not(Key in ['0'..'9',
#8]) then Key := #0;
//Получаем договор по его номеру в списке
procedure
TCorrect.Edit1Change(Sender: TObject);(Edit1.Text = '') then
Exit;(StrToInt(Edit1.Text) > Main.NPO.Struct.Counter) then;:=
Main.NPO.Struct.GetByNumber(StrToInt(Edit1.Text));.Text :=
IntToStr(P^.Number);.Text := P^.StartDate;(P^.Done)Edit4.Text :=
'Завершён'Edit4.Text := 'Не завершён';.Text := IntToStr(P^.Price);
//Кнопка
"Применить"TCorrect.Button1Click(Sender: TObject);^.Number :=
StrToInt(Edit2.Text);^.StartDate := Edit3.Text;(Edit4.Text = 'Завершён')P^.Done
:= TrueP^.Done := False;^.Price :=
StrToInt(Edit5.Text);;TCorrect.FormShow(Sender: TObject);.Text :=
'1';Change(Sender);;.
МодульStructures.Structures;,
//Модуль для работы с TStringGrid; //Модуль
с
функциями
StrToInt и т.д.
//Типы массивов для передачи информации о втором
и первом уровнях иерархии
TCities = Array[1..20] of
String[20];= Array[1..20, 1..6] of LongWord;
//Тип - указатель на элемент третьего уровня
иерархии
PLevel3 = ^TLevel3;
//Запись - элемент третьего уровня иерархии
TLevel3 = Record: LongWord; //Номер
расчётного счёта : PLevel3
//Указатель на следующий элемент в третьем уровне структуры
end;
//Тип - указатель на элемент второго уровня
иерархии
PLevel2 = ^TLevel2;
//Запись - элемент второго уровня иерархии
TLevel2 = Record: String[20];
//Название города: PLevel3;
//Указатель на третий уровень иерархии (список номеров отделений банка в
городе)
Next : PLevel2
//Указатель на следующий элемент во втором уровне структуры
end;
//Тип - указатель на элемент первого уровня
иерархии
PLevel1 = ^TLevel1;
//Запись - элемент первого уровня иерархии
TLevel1 = Record: Word; //Номер
хоздоговора: String[10];
//Дата заключения
Done : Boolean;
//Признак завершения
Price : Word;
//Цена работ по договору
Cities : PLevel2;
//Указатель на второй уровень иерархии
Next : PLevel1
//Указатель на следующий элемент в первом уровне структуры
end;
//Класс 3-ёх уровневой иерархической структуры
THierarchList
= class
private
Head: PLevel1;
//Указатель на голову списка (первый уровень)
Current:
PLevel1; //Текущий
указатель в списке (первый уровень)
Count: Word;
//Количество элементов в списке на первом уровне
procedureSwap(P1,
P2: PLevel1);
//Процедура менят местами два узла первого уровня иерархии (для сортировки)
publicCounter: Word read Count;
//Добавление члена ВТК в иерархический список
(параметры - это все нужные поля в структуре)
procedure Add(S: String; D: Boolean;
N, P: Word;City: TCities; Cnt: Byte; var Accounts: TAccounts);(SG:
TStringGrid); //Вывод
структуры на форму
procedureSortingUp;
//Сортировка по возрастанию
procedureSortingDown;
//Сортировка по убыванию
function SearchByNumber(N: Word):
TLevel1; //Поиск договора по номеру(N:
Word): PLevel1;
//Получение договора по номеру в списке (для корректировки)
end;
implementation
//Добавление члена ВТК в иерархический список
procedure THierarchList.Add(S:
String; D: Boolean; N, P: Word;City: TCities; Cnt: Byte; var Accounts:
TAccounts);: PLevel1;, NewL2: PLevel2;, NewL3: PLevel3;, J: Byte;
New(NewNode);
//Выделяем память под узел первого уровня
with NewNode^ do:= NIL; //Заполняем
поля первого уровня:= S;:= N;:= P;:= D; := NIL;
For
I := 1 To
Cnt do
//Начинаем заполнять второй уровень
begin
New(NewL2);
//Выделяем память под узел второго уровня
if (Cities
= NIL) //Вставляем его
во второй уровень
then Cities := NewL2CurC^.Next :=
NewL2;2^.City
:= City[I];
//Заполняем поле (город)
NewL2^.Next
:= NIL; //Указатель на
следущий - NIL
NewL2^.Accounts
:= NIL; //Начинаем
заполнять третий уровень
For J := 2 to Accounts[I, 1] do
New(NewL3);
//Выделяем память под узел третьего уровня
NewL3^.Account
:= Accounts[I,
J]; //Заполняем поле
(номер отделения банка)
NewL3^.Next
:= NIL; //Указатель на
следущий - NIL
if (NewL2^.Accounts
= NIL) //Вставляем его
на третий уровень
then NewL2^.Accounts :=
NewL3CurN^.Next := NewL3;:= NewL3;:= NewL2;
if (Current
= NIL) //Помещаем узел
первого уровня в наш список
then Head := NewNodeCurrent^.Next :=
NewNode;
:= NewNode;
Inc(Count)
//Увеличиваем количество элементов в списке
end;
//Возвращает указатель на исполнителя по номеру
в списке
function
THierarchList.GetByNumber(N: Word): PLevel1;: Word;:= Head;I := 2 to N do:=
Current^.Next;:= Current;
//Поиск по
фамилииTHierarchList.SearchByNumber(N: Word): TLevel1;.Number := 0;.StartDate
:= '';.Done := False;.Price := 0;
//Начинаем двигаться по списку
Current
:= Head;
While (Current<>NIL)
do
begin
//Сравниваем текущую фамилию с заданной
if (Current^.Number
= N) then
begin //Если
совпадает, то запоминаем результат и выходим
Result := Current^;;:= Current^.Next
//Иначе двигаемся по списку дальше
end;
//Вывод структуры на форму в StringGrid
procedure THierarchList.Show(SG:
TStringGrid);, J, L: Byte;: PLevel2;: PLevel3;I := 1 to 30 do //Чистим
StringGridJ := 0 to 10 do.Cells[J,I] := '';:= 1;:= Head;I := 1 to Count do
//Проход по первому уровню.Cells[0, L] := IntToStr(Current^.Number); //Выводим
поля узла первого уровня.Cells[1, L] :=
Current^.StartDate;(Current^.Done)SG.Cells[2, L] := 'Завершён'.Cells[2,
L] := 'Не завершён';
SG.Cells[3,L] := IntToStr(Current^.Price);
:= Current^.Cities;
//Начинаем просматривать второй уровень структуры
While (CurC<>NIL)
do
begin
SG.Cells[4,L]
:= CurC^.City;
//Выводим поле узла второго уровня (город)
CurN := CurC^.Accounts;
//И начинаем просматривать третий уровень
While (CurN<>NIL)
do
Begin//Выводим
поле третьего уровня (счёт)
SG.Cells[5,L] := SG.Cells[5,L] +
IntToStr(CurN^.Account) + ', '; := CurN^.Next
//И движемся дальше по птрьему уровню
end;
Inc(L);
CurC := CurC^.Next
//Здесь движемся дальше по второму уровню
end;:= Current^.Next //А здесь по
первому...;
//Cортировка
прямым выбором по убыванию
procedure
THierarchList.SortingDown;, J: Word;: PLevel1;:= Head;I := 1 to Count-1 do:=
Max^.Next;J := 1 to Count - I do //Сравниваем
текущий элемент с первым неупорядоченным
if (Max^.Price < Current^.Price)
then(Max,
Current); //Меняем их
местами если надо
Current
:= Current^.Next
//И движемся дальше по списку
end;:= Max^.Next;
//Cортировка
прямым выбором по возрастанию
procedureTHierarchList.SortingUp;
var, J: Word;: PLevel1;:= Head;I :=
1 to Count-1 do:= Min^.Next;J := 1 to Count - I do
//Сравниваем текущий элемент с первым неупорядоченным
if (Min^.Price > Current^.Price)
then(Min,
Current); //Меняем их
местами если надо
Current
:= Current^.Next
//И движемся дальше по списку
end;:= Min^.Next;
//Обмен местами в списке первого уровня
procedure THierarchList.Swap(P1, P2:
PLevel1);: String[10];: Boolean;: Word;: Word;: PLevel2;
//Запомнили первый договор:=
P1^.StartDate;:= P1^.Done;:= P1^.Number;:= P1^.Price;:= P1^.Cities;
//Записали в него второй
P1^.StartDate
:= P2^.StartDate;
P1^.Done := P2^.Done;^.Number :=
P2^.Number;^.Price := P2^.Price;^.Cities := P2^.Cities;
//А во второй записали сохранённый первый
P2^.StartDate :=
TempStartDate;^.Done := TempDone;^.Number := TempNumber;^.Price := TempPrice;2^.Cities
:= TempCities;
//В итоге договоры поменялись местами
end;.
МодульOrganizations.Organizations;,
//Модуль для работы с TStringGrid, //Модуль
с
функциями
StrToInt и т.д.;
//Модуль с классом 3-ёх уровневой иерархической структуры
type
//Запись - ХозДоговор
TXDogovor
= Record
Number : Word;
//Номер договора
StartDate
: String[10]; //Дата
заключения договора
FinishDate
: String[10]; //Дата
завершения договора
Theme : String[25];
//Тема договора,
Organization:
String[25];
//Наименование организации - заказчика работ
Done : Boolean;
//Признак завершения
Price : Word
//Стоимость договора в тыс. рублей
end;
//Запись - Исполнитель ХД и член ВТК
TMemeberWTK = Record: String[20];
//Фамилия: String[20]; //Имя: String[20]; //Отчество: String[10]; //Год
рождения: String[10]; //Код ХД: Boolean; //Признак руководитель/рядовой член
ВТК
: Word; //Причитающаяся
по договору сумма вознаграждения
Address
: String[20]; //Домашний
адрес
BankNumber:
Word; //Номер отделения
сбербанка
Account
: LongWord //Расчетный счет
исполнителя
end;
//Запись - Атрибуты отделения сбербанка
TBank = Record
Number : Word;
//Номер отделения
City : String[20];
//Город, в котором находится отделение
Address
: String[20]; //Адрес без
указания города
Partition:
String[20];
//Наименование отделения
Code : Word
//3-хзначный банковский код отделения
end;
TNPO = class
//Класс НПО - научно-производственная организация
private
XD: Array[1..50]
ofTXDogovor; //Массив с
договорами
WTK: Array[1..30]
ofTMemeberWTK; //Массив и
исполнителями
Bank: Array[1..20]
ofTBank; //Массив с
отделениями банков
XDCount:
Integer; //Количество
договоров
WTKCount:
Integer; //Количество
исполнителей
BankCount:
Integer; //Количество
отделений банка
XDTable:
TStringGrid; //StringGrid
для ХозДоговоров
WTKTable:
TStringGrid; //StringGrid
для исполнителей договоров
BankTable:
TStringGrid; //StringGrid
для отделений банков
functionGetCityByNumber(N:
Word): String;
//ПОлучение города по номеру отделения банка
public
Struct: THierarchList;
//Иерархический список
propertyCountXD:
IntegerreadXDCount;
//Свойство: Количество договоров
propertyCountWTK:
IntegerreadWTKCount;
//Свойство: Количество исполнителей
propertyCountBank:
IntegerreadBankCount;
//Свойство: Количество отделений банка
constructorCreate(SG1, SG2, SG3:
TStringGrid); //КонструкторLoadXD(FileName:
String); //Открытие файла хоздоговоровLoadWTK(FileName: String); //Открытие
файла исполнителейLoadBank(FileName: String); //Открытие файла отделений
банкаShowXD; //Вывод списка хоздоговоров на форму; //Вывод
списка исполнителей на форму
procedureShowBank;
//Вывод списка отделений банков на форму
procedureCreateList;
//Формирование иерархического списка
end;
implementation
//Сохраняем StringGrid'ы
для всех таблиц
constructor
TNPO.Create(SG1,
SG2, SG3:
TStringGrid);
begin:= SG1;:= SG2;
:= SG3
end;
//Формирование иерархического списка (по условию
задания)
procedure TNPO.CreateList;, J, K:
Byte;:
Boolean;
Cities: TCities;
//Массив с городами для 2-ого уровня иерархии
Accounts:
TAccounts; //Массив со
счетами для 3-его уровня иерархии
CountC: Byte;
//Количество городов
begin
Struct := THierarchList.Create;
//Создаём структуру
ForI := 1 toXDCountdo
//Просматриваем всех договоров
withXD[I]
do
begin //Начинаем
формировать для него иерархию
FillChar(Accounts, sizeof(Accounts),
0);:= 0; //Сначала количество городов = 0:= 1 toWTKCountdo //Просматриваем
всех
исполнителей(Number
= StrToInt(Copy(WTK[J].CodeXD, 1, 2))) then//И
если
совпал
номер
договора
P := False;
//То добавляем в структуру город и/или счёт
For K := 1 to CountC do(Cities[K] =
GetCityByNumber(WTK[J].BankNumber)) then:= True;(Accounts[K, 1]);[K,
Accounts[K, 1]] := WTK[J].Account;;Not(P) then(CountC);[CountC] :=
GetCityByNumber(WTK[J].BankNumber);[CountC, 1] := 2;[CountC, 2] := WTK[J].Account;.Add(StartDate,
Done, Number, Price, Cities, CountC, Accounts) //Добавляем получившуюся
информацию в структуру
end;
//Возвращает название города по номеру отделения
банка
function TNPO.GetCityByNumber(N:
Word): String;: Byte;:= '';I := 1 to BankCount do(Bank[I].Number = N) then:=
Bank[I].City;
end
end;
//Открытие файла отделений банка
procedure TNPO.LoadBank(FileName:
String);: File of TBank;(F, FileName);(F);:= 0;Not(EoF(F)) do(BankCount);(F,
Bank[BankCount]);
CloseFile(F)
end;
//Открытие файла исполнителей
procedure TNPO.LoadWTK(FileName:
String);: File of TMemeberWTK;(F, FileName);(F);:= 0;Not(EoF(F))
do(WTKCount);(F, WTK[WTKCount]);
CloseFile(F)
end;
//Открытие файла хоздоговоров
procedure TNPO.LoadXD(FileName:
String);: File of TXDogovor;(F, FileName);(F);:= 0;Not(EoF(F)) do(XDCount);(F,
XD[XDCount]);
CloseFile(F)
end;
//Вывод списка отделений банков на форму
procedure TNPO.ShowBank;: Byte;I :=
1 to BankCount doBank[I] do.Cells[0,I] := IntToStr(Number);.Cells[1,I] :=
City;.Cells[2,I] := Address;.Cells[3,I] := Partition;.Cells[4,I] :=
IntToStr(Code);;
end;
//Вывод списка исполнителей на форму
procedure TNPO.ShowWTK;: Byte;I := 1
to WTKCount doWTK[I] do.Cells[0,I] := Surname;.Cells[1,I] := Name;.Cells[2,I]
:= Patronymic;.Cells[3,I] := BirthYear;.Cells[4,I] :=
CodeXD;(IsDirector)WTKTable.Cells[5,I] := 'Руководитель'WTKTable.Cells[5,I] :=
'Рядовой член';.Cells[6,I] := IntToStr(Premium);.Cells[7,I] :=
Address;.Cells[8,I] := IntToStr(BankNumber);.Cells[9,I] := IntToStr(Account)
end
end;
//Вывод списка договоров на форму
procedure TNPO.ShowXD;: Byte;I := 1
to XDCount doXD[I] do.Cells[0,I] := IntToStr(Number);.Cells[1,I] :=
StartDate;.Cells[2,I] := FinishDate;.Cells[3,I] := Theme;.Cells[4,I] :=
Organization;(Done)XDTable.Cells[5,I] := 'Завершён'XDTable.Cells[5,I] := 'Не
завершён';.Cells[6,I] := IntToStr(Price);.