По методичке сделал с двумя файлами, а вот как с 3-мя то сделать никак не разберусь.
Разбиение ещё более-менее понятно, а вот слияние
Программа также в архиве приложена
type
TKey = Integer;
TData = Array of TKey;
TFormSimpleMerging = class(TForm)
ChartMain: TChart;
Panel1: TPanel;
Panel2: TPanel;
ButtoStartTest: TButton;
Series1: TLineSeries;
Panel3: TPanel;
MemoData: TMemo;
Label1: TLabel;
Label2: TLabel;
BitBtnSaveChartBmp: TBitBtn;
SavePictureDialogChart: TSavePictureDialog;
Series2: TLineSeries;
SpinEditStep: TSpinEdit;
SpinEditTestsCount: TSpinEdit;
CheckBoxWorstData: TCheckBox;
CheckBoxEnableAnimation: TCheckBox;
procedure BitBtnSaveChartBmpClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure ButtoStartTestClick(Sender: TObject);
procedure ResetChart(const GraphStep, Step, TestsCount: Integer);
procedure FillRandomData(var DataFile: TFileStream; const Amount: Integer);
procedure FillWorstData(var DataFile: TFileStream; const Amount: Integer);
procedure PrintData(var DataFile: TFileStream; const Header: String);
function SortSimpleMerging(var DataFile: TFileStream; const TempFilesCount: Byte): Cardinal;
private
DataSet: TData;
DataFile: TFileStream;
public
end;
var
FormSimpleMerging: TFormSimpleMerging;
implementation
{$R *.dfm}
procedure TFormSimpleMerging.ButtoStartTestClick(Sender: TObject);
var
Step, TestsCount, i, Iterations: Integer;
begin
Step:= SpinEditStep.Value;
TestsCount:= SpinEditTestsCount.Value;
ResetChart(1,Step,TestsCount);
ChartMain.Series[0].AddXY(0,0);
// FillRandomData(DataFile,100);
// PrintData(DataFile,'Ïðîâåðî÷êà');
for i:= 1 to TestsCount do
begin
if CheckBoxWorstData.Checked then
FillWorstData(DataFile,Step*i)
else
FillRandomData(DataFile,Step*i);
// PrintData(DataFile,'Èñõîäíûé íàáîð äàííûõ:');
Iterations:= SortSimpleMerging(DataFile,2);
// PrintData(DataFile,'Óïîðÿäî÷åííûé íàáîð äàííûõ:');
MemoData.Lines.Add('Êîëè÷åñòâî îïåðàöèé: '+IntToStr(Iterations));
ChartMain.Series[0].AddXY(Step*i,Iterations);
if CheckBoxEnableAnimation.Checked then
ChartMain.Refresh;
end;
end;
procedure TFormSimpleMerging.FormCreate(Sender: TObject);
var
GraphStep, Step, TestsCount: Integer;
begin
Step:= SpinEditStep.Value;
TestsCount:= SpinEditTestsCount.Value;
ResetChart(1,Step,TestsCount);
DataFile:= TFileStream.Create('TestFile.txt',fmCreate,fmShareDenyWrite);
end;
procedure TFormSimpleMerging.ResetChart(const GraphStep, Step, TestsCount: Integer);
var
i, N: Integer;
O: Extended;
SeriesFunction: TLineSeries;
begin
ChartMain.Series[0].Clear;
ChartMain.Series[1].Clear;
ChartMain.Refresh;
ChartMain.Series[1].AddXY(0,0);
N:= 1;
While (N <= Step*TestsCount) do
begin
O:= Log2(N);
ChartMain.Series[1].AddXY(N,O);
N:= N + GraphStep;
end;
end;
procedure TFormSimpleMerging.FillRandomData(var DataFile: TFileStream; const Amount: Integer);
var
Buffer: TKey;
i: Integer;
begin
Randomize;
DataFile.Seek($0,soFromBeginning);
for i:= 0 to Amount-1 do
begin
Buffer:= Random(Amount*10);
DataFile.Write(Buffer,SizeOf(Buffer));
end;
end;
procedure TFormSimpleMerging.FillWorstData(var DataFile: TFileStream; const Amount: Integer);
var
Buffer: TKey;
i: Integer;
begin
Randomize;
DataFile.Seek($0,soFromBeginning);
for i:= 0 to Amount-1 do
begin
Buffer:= Amount-i;
DataFile.Write(Buffer,SizeOf(Buffer));
end;
end;
procedure TFormSimpleMerging.PrintData(var DataFile: TFileStream; const Header: String);
var
Buffer: TKey;
i: Integer;
Str: String;
begin
Str:= '';
DataFile.Seek($0,soFromBeginning);
for i:= 0 to (DataFile.Size div SizeOf(Buffer)) - 1 do
begin
DataFile.Read(Buffer,SizeOf(Buffer));
Str:= Str + IntToStr(Buffer) + '; ';
end;
MemoData.Lines.Add(Header);
MemoData.Lines.Add(Str);
end;
function TFormSimpleMerging.SortSimpleMerging(var DataFile: TFileStream; const TempFilesCount: Byte): Cardinal;
var
TempFiles: Array of TFilestream;
Buffer, Buffer2: TKey;
i, k, KeysToRead, CurFile, FileSwitch: Integer;
RecordsCount, j, Iterations: Cardinal;
Limits: Array of Word;
Str: String;
begin
SetLength(TempFiles,TempFilesCount);
SetLength(Limits,TempFilesCount);
RecordsCount:= DataFile.Size div SizeOf(TKey);
Iterations:= 0;
for i:= 0 to TempFilesCount - 1 do
begin
TempFiles[i]:= TFileStream.Create('TempFile'+IntToStr(i+1)+'.txt',fmCreate,fmShareDenyWrite);
end;
// Îñíîâíîé öèêë ñîðòèðîâêè
KeysToRead:= 1;
for i:= 0 to Ceil(LogN(TempFilesCount,RecordsCount))-1 do
begin
Inc(Iterations);
// Ðàçáèåíèå ôàéëà âî âñïîìîãàòåëüíûå
CurFile:= 0;
FileSwitch:= 0;
Str:= '';
DataFile.Seek($0,soFromBeginning);
for j:= 0 to TempFilesCount - 1 do
begin
TempFiles[j].Size:= 0;
TempFiles[j].Seek($0,soFromBeginning);
end;
for j:= 0 to RecordsCount - 1 do
begin
// Str:= Str + IntToStr(CurFile) + '; ';
DataFile.Read(Buffer,SizeOf(Buffer));
TempFiles[CurFile].Write(Buffer,SizeOf(Buffer));
Inc(FileSwitch);
// Inc(Iterations,2);
if (FileSwitch = KeysToRead) then
begin
FileSwitch:= 0;
if (CurFile < TempFilesCount - 1) then
Inc(CurFile)
else
CurFile:= 0;
end;
end;
// PrintData(TempFiles[0],'Ôàéë 1');
// PrintData(TempFiles[1],'Ôàéë 2');
// MemoData.Lines.Add(Str);
// Îáðàòíîå ñëèÿíèå
CurFile:= 0;
FileSwitch:= 0;
Str:= '';
DataFile.Seek($0,soFromBeginning);
for j:= 0 to TempFilesCount - 1 do
TempFiles[j].Seek($0,soFromBeginning);
TempFiles[0].Read(Buffer,SizeOf(Buffer));
// Inc(Iterations);
if (KeysToRead <= TempFiles[0].Size div SizeOf(Buffer)) then
Limits[0]:= KeysToRead
else
Limits[0]:= TempFiles[0].Size div SizeOf(Buffer);
TempFiles[1].Read(Buffer2,SizeOf(Buffer2));
// Inc(Iterations);
if (KeysToRead <= TempFiles[1].Size div SizeOf(Buffer2)) then
Limits[1]:= KeysToRead
else
Limits[1]:= TempFiles[1].Size div SizeOf(Buffer2);
for j:= 0 to RecordsCount - 1 do
begin
if (Limits[1] = 0)
or (Buffer < Buffer2) and (Limits[0] > 0) then
begin
DataFile.Write(Buffer,SizeOf(Buffer));
TempFiles[0].Read(Buffer,SizeOf(Buffer));
Dec(Limits[0]);
// Inc(Iterations,2);
end
else
begin
DataFile.Write(Buffer2,SizeOf(Buffer2));
TempFiles[1].Read(Buffer2,SizeOf(Buffer2));
Dec(Limits[1]);
// Inc(Iterations,2);
end;
if (Limits[0] = 0) and (Limits[1] = 0) then
begin
if (TempFiles[0].Position < TempFiles[0].Size + 1) then
Limits[0]:= KeysToRead;
if (TempFiles[1].Position < TempFiles[1].Size + 1) then
Limits[1]:= KeysToRead;
end;
end;
// PrintData(DataFile,'Îñíîâíîé ôàéë');
// MemoData.Lines.Add('');
KeysToRead:= KeysToRead * 2;
end;
for i:= 0 to TempFilesCount - 1 do
begin
TempFiles[i].Destroy;
end;
Result:= Iterations;
end;
procedure TFormSimpleMerging.BitBtnSaveChartBmpClick(Sender: TObject);
begin
if SavePictureDialogChart.Execute then
begin
ChartMain.SaveToBitmapFile(SavePictureDialogChart.FileName);
end;
end;
end.