Quote
On Sat, 14 Oct 1995, David Koons wrote:
> >> I've tried several times to write an efficient record sorter/packer
> >> to no avail... This is what I'm looking for:
> >> Some code for sorting the records by MyInfo.IntInfo would be nice too.
> >> Again, I have done it, but not efficiently...
> >Post me your routines and I'll try to help you ...
> Took a while for me to answer, had to find time to sit and write some sample
> code... Here's how I purge deleted records:
> .....
> That's it in a nutshell, of course I always add the IOResult checks and
> FileExist functions in my actual programs... I've heard of faster ways to do
> this without all the disk activity by moving undeleted records from the end of
> the data file to overwrite a deleted record towards the beginning of the data
> file, then just trunacating the data file when done... This would be much more
> efficient, faster, and would not require makeing a TEMP file or accessing the
> disk as much...
That's the best way I find. You can store all the contents of the file in
memory (only not-to-purge records) and then rewrite over the original file.
But the other method (making a temp{*word*203}file in the hard disk and then
rename it) gives you more security (if your system hangs during the
expunging operation you don't loose the original data). I think so, but
may be I'm wrong ...
Quote
> As for the sorting methods I use, I basically write the contents of the record
> file to an array (much faster than file I/O operations)... Then I loop
> through the array comparing each entry with the next entry, if the second
> one is larger, they get swapped and a boolean variable gets toggled to
> true... With the start of each pass through the array, the boolean variable
> is set to false, it only goes true if values are swapped... I have to
> continue through the loop until no values are swapped, that means they are
> all in ascending order...
> I know there's faster sorting methods than bubblesort, but I haven't been able
> to write it... I've read about using Linked Lists to do this, but I really
> don't understand enough about using them...
Here you are an example of sorting records from a file of registers.
First, the program creates a file of registers with numeric and
alphanumeric fields. When the file is created, reads the contents of
fields of one of the numeric fields (for example). For the sorting uses
the ShellSort procedure, that sorts the array containing the numeric
data (using a temp{*word*203}array of pointers), returning an array with the
values of positions of the records in the file. Not linked lists, but the
sorting process is very fast, and you can sort up to 32000 records (aprox.).
My English may be not very good, but hope you understand almost all ...
... if any comment, please e-mail me.
Regards,
Aitor.
******** Hau ez da Espainia ... Euskal Herria Askatu !!! *******
*** This is not Spain ... Freedom for the Basque Country !!! ***
***************** epago...@lgdx02.lg.ehu.es ********************
Here it's the code ... hope this helps you !!
{------------------- cut here ----------------- cut here ----------------}
Program ShellSortExample;
Uses
Crt;
Const
MaxNumCustomers = 3200; { Number of records ... up to 32000 (aprox.) }
Type
RCustomer = Record
Name : String[20];
Address : String[100];
Country : String[30];
TelNum : LongInt;
CP : Word;
End;
TOrder = Array[1..MaxNumCustomers] of Word;
Var
FCustomers : File of RCustomer;
d1 : RCustomer;
i : Word;
Order : TOrder;
Procedure CreateFCustomers;
Var
F : RCustomer;
Begin
WriteLn('Creating ',MaxNumCustomers,' registers file ...');
ReWrite(FCustomers);
Randomize;
for i:=1 to MaxNumCustomers do
begin
Seek(FCustomers,FileSize(FCustomers));
F.Name := 'Aitor Gomez Gonzalez';
F.Address := 'Aurrekoetxea 1, 2. dcha.';
F.Country := 'Euskal Herria';
F.TelNum := Random(255)*Random(255);
F.CP := Random(255)*Random(255)*Random(10);
Write(FCustomers,F);
end;
WriteLn(MaxNumCustomers,' registers file created');
End; { CreaFichCustomeres }
Procedure ShellSort(Var A:TOrder);
Type
TOrderPtr = ^TOrder;
Var
B : TOrderPtr; { Temp{*word*203}table }
Hecho : Boolean;
Salto : Word;
j,k : Word;
l : Word;
Begin
New(B);
For i:=1 to MaxNumCustomers do
B^[i]:=i;
Salto:=MaxNumCustomers;
While Salto>1 do
Begin
Salto:=Salto div 2;
Repeat
Hecho:=True;
For j:=1 to MaxNumCustomers-Salto do
Begin
i:=j+Salto;
if A[j]>A[i] then
Begin
l:=B^[j];
k:=A[j];
B^[j]:=B^[i];
A[j]:=A[i];
B^[i]:=l;
A[i]:=k;
Hecho:=False;
End;
End;
Until Hecho;
End;
{ When sorted values are stored in 'B' array, we store'em in 'A' again and }
{ dispose 'B' from memory. Using temp{*word*203}pointers array 'B' we can sort }
{ double number of records ... }
For i:=1 to MaxNumCustomers do
A[i]:=B^[i];
Dispose(B);
End; { ShellShort }
begin
Assign(FCustomers,'Customer.Dat');
ClrScr;
{ Creation of 'Customer.Dat' }
{$I-}
Reset(FCustomers);
Close(FCustomers);
{$I+}
If (IOResult=0)
then
Begin
WriteLn('File ''Customer.Dat'' exist ... Overwrite? [Y/N] ');
If UpCase(ReadKey)='Y' then
CreateFCustomers
Else Halt(1);
End
Else
CreateFCustomers;
{ Open 'Customer.Dat' for reading }
Reset(FCustomers);
{ Reading of 'CP' fields from all the 'RCustomer' registers in the file }
{ and storing them in the table 'Order' }
i:=0;
Seek(FCustomers,0);
WriteLn('Reading ''CP'' fields from file ''Customer.Dat'' ...');
For i:=1 to MaxNumCustomers do
Begin
Read(FCustomers,d1);
Order[i]:=d1.CP;
End;
WriteLn('Sorting ',MaxNumCustomers,' registers ...');
ShellSort(Order); { <-------- Call to the sorting procedure !!! }
WriteLn(MaxNumCustomers,' registers sorted');
{ Uncomment the following to display the sorted values }
{ For i:=1 to MaxNumCustomers do
Begin
Seek(FCustomers,Order[i]-1);
Read(FCustomers,d1);
WriteLn('Register n. ',Order[i]:5,' : ',d1.CP:5);
End;
Close(FCustomers);}
Repeat Until KeyPressed;
end.
{------------------- cut here -------------- cut here ------------------}