{ From: pierre.tourigny@bbs.synapse.net (Pierre Tourigny) > I'm looking for an external sort procedure in TP 6 / 7 which allows me > to sort a file containing 20,000 records of the following type: > RECORD > Phone : String[8]; > L_Name : String[27]; > F_Name : String[27]; > END; > It must sort on Phone#. I could write it myself but I really need it > in a hurry, so if anyone out there has an old sort procedure that I > could modify to my own needs, I'd really apriciate it. Speed is of no > importance. Here's a modified merge sort that I used to sort a list of 260,000 words. It takes little memory and it's a fast O(NlogN) procedure. The modification is that it goes external at k=1024 instead of at k=1. } program dictri; {94-11-10, Pierre Tourigny, pierre.tourigny@bbs.synapse.net} uses strings; const k1 = 1024; strentree : string = 'c:\bp\bin\pas\diko2.dpt'; strsortie : string = 'c:\bp\bin\pas\diko2.new'; type tmot = array[0..62] of char; var source,ff1,ff2,fg1,fg2 : text; sourcebuf,ff1buf,ff2buf,fg1buf,fg2buf : array[0..4095] of char; k,maxmot : longint; fini : boolean; procedure init; begin assign(source,strentree); settextbuf(source,sourcebuf); reset(source); assign(ff1,'$f1$'); settextbuf(ff1,ff1buf); rewrite(ff1); assign(ff2,'$f2$'); settextbuf(ff2,ff2buf); rewrite(ff2); assign(fg1,'$g1$'); settextbuf(fg1,fg1buf); rewrite(fg1); assign(fg2,'$g2$'); settextbuf(fg2,fg2buf); rewrite(fg2); maxmot := 0; fini := false; end; procedure passe1; type tmots = array[0..k1] of tmot; pmots = ^tmots; var i,j : integer; item : pmots; switch : boolean; Procedure inSort(item : pmots; last : integer); var i,j,span : integer; begin span := last shr 1; while span > 0 do begin for i := span to last-1 do begin for j := (i-span+1) downto 1 do if strcomp(item^[j],item^[j+span]) <= 0 then break else begin strcopy(item^[0],item^[j]); strcopy(item^[j],item^[j+span]); strcopy(item^[j+span],item^[0]); end; end; span := span shr 1; end; end; begin new(item); fillchar(item^,sizeof(item^),0); switch := true; while not eof(source) do begin j := 0; for i := 1 to k1 do begin inc(j); readln(source,item^[i]); if eof(source) then break; end; inc(maxmot,j); insort(item,j); for i := 1 to j do if switch then writeln(ff1,item^[i]) else writeln(ff2,item^[i]); switch := not switch; end; dispose(item); close(source); writeln('Passe 1 termin,e Nombre de mots: ',maxmot); end; procedure merge (lek : longint; var f1,f2,g1,g2 : text); var outswitch : boolean; winner : integer; used : array[1..2] of longint; fin : array[1..2] of boolean; current : array[1..2] of tmot; numg1,numg2 : longint; procedure getrecord (i : integer); begin if (used[i] = lek) or ((i = 1) and eof(f1)) or ((i = 2) and eof(f2)) then fin[i] := true else begin inc(used[i]); if i = 1 then readln(f1,current[1]) else readln(f2,current[2]); end; end; begin outswitch := true; flush(g1); rewrite(g1); flush(g2); rewrite(g2); flush(f1); reset(f1); flush(f2); reset(f2); numg1 := 0; numg2 := 0; while not eof(f1) or not eof(f2) do begin fillchar(used,sizeof(used),0); fillchar(fin,sizeof(fin),false); fillchar(current,sizeof(current),0); getrecord(1); getrecord(2); while not fin[1] or not fin[2] do begin if fin[1] then winner := 2 else if fin[2] then winner := 1 else if strcomp(current[1],current[2]) < 0 then winner := 1 else winner := 2; if outswitch then begin writeln(g1,current[winner]); inc(numg1); end else begin writeln(g2,current[winner]); inc(numg2); end; getrecord(winner); end; outswitch := not outswitch; end; fini := numg2 = 0; end; procedure externe; var i : integer; switch : boolean; begin i := 1; k := k1; switch := true; while not fini {maxmot > k} do begin inc(i); write('Passe ',i:2,' (k = ',k:7,')'); if switch then merge(k,ff1,ff2,fg1,fg2) else merge(k,fg1,fg2,ff1,ff2); writeln(' termin,e'); switch := not switch; k := k * 2; end; close(ff2); erase(ff2); close(fg2); erase(fg2); close(ff1); close(fg1); assign(ff2,strsortie); {$I-} reset(ff2); {$I+} if ioresult = 0 then erase(ff2); if switch then begin rename(ff1,strsortie); erase(fg1); end else begin rename(fg1,strsortie); erase(ff1); end; end; begin {main} init; passe1; externe; end.