program Quick_Shell_Sort; {$APPTYPE CONSOLE} uses SysUtils; This line must be commented out by adding //. By commenting out this line you // will modify the source and therefore take full responsibility for this document/code as used // by you. // You may not publish or in any other way make this document or code or copy thereof // available to the public without QxSource written consent. // You or your organization may in other ways use this code or information to your benefit. // QxSource is the sole owner of this document. By using this document you acknowledge that: // A) QxSource is in no way responsible for this document's/code's use or functionality. // B) QxSource is in no way responsible for damage caused by any use of this document/code // or it's functionality. // C) QxSource provides no warranties for the contents, functionality or use of this document. // D) This document is provided as is for educational purpose only. //We wish you the best use of this educational information. //==================================================================== const MAXLIST = 100000; type TArray = array[0..MAXLIST-1] of Integer; type TArrayP = ^TArray; var RecCnt:Int64; //================================================= // ShellSort non recursive sort // procedure ShellSort(var List:Tarray; Asize:Integer); var i,k,Offset,LoopLimit,Switch,tmp:Integer; begin k := 1; repeat k := 3 * k + 1; // x3 is uneven and nice to not cmp same vals until k > Asize; Offset := {Asize} k div 3; //Work on h=h*3+1.... while Offset > 0 do // if offset is 0 => done! (offset /=2...see below) begin LoopLimit := Asize - Offset; //First time ~List/3... repeat begin Switch := -1; //-1 to show no swaps done for i := 0 to LoopLimit-1 do //LoopLimit~ Switch-Offset+1 begin //inc(cnt); if List[i] > List[i+Offset] then //Distant compare begin //Swap tmp:=List[i]; List[i] := List[i+Offset]; List[i+Offset] := tmp; Switch := i end; end; //if negative none will be done LoopLimit := Switch-Offset+1; //Redo up till second to last swap end; until Switch < 0; //no swaps done Offset := Offset div 3; //shrink offset so ..looks like std bubble @ end end; end; //End ShellSort //================================================= // QuickSort recursive sort // procedure QuickSort(var List: TArray; Low, High: integer); var LowIx, HighIx, tmp, PivotVal: integer; begin Inc(RecCnt); // If you want plain Quicksort remove the code // below if RecCnt > 30 then if RecCnt > 30 then begin //Used to stop deep recusion ShellSort( TArrayP( @List[Low] )^ , High+1-Low); exit; end; //cnt:=max(cnt,RecCnt); //So we can show max recusion LowIx:=Low; //Index moving, Low-> PivotVal HighIx:=High; //Index moving, High-> PivotVal PivotVal:=List[(Low+High) div 2]; //Get PivotVal while LowIx <= HighIx do begin while List[LowIx] < PivotVal do inc(LowIx); //Move LowIn up... while List[HighIx] > PivotVal do dec(HighIx); //Move HighIx up... if (LowIx <= HighIx) then begin //Indexes did not meet so swap... tmp := List[LowIx]; List[LowIx] := List[HighIx]; List[HighIx] := tmp; inc(LowIx); dec(HighIx); end; end; // Recursive Calls if Low < HighIx then QuickSort(List, Low, HighIx); if LowIx < High then QuickSort(List, LowIx, High); Dec(RecCnt); end; //End QuickSort //================================================= // BubbleSort not used // procedure BubbleSort(var List:Tarray; Asize:Integer); var i,j,tmp:Integer; begin for i:=0 to Asize-2 do //Loop by all members for j:=i+1 to Asize-1 do //Loop from i to all members begin //inc (Cnt); if List[i] > List[j] then begin //If bottom [i] is > move it up tmp := List[i]; List[i] := List[j]; List[j] := tmp; end; end; end; // //================================================= var List:TArray; var x:Integer; var Ok:Boolean; begin Ok := True; Randomize; for x:=1 to MAXLIST do List[x-1]:= Random(50000); QuickSort(List, 0, MAXLIST); for x:=0 to MAXLIST-2 do if List[x] > List[x+1] then begin Writeln('Bad sort'); Ok := False; break; end; if Ok then Writeln('Ok! Sorted: ' + IntToStr(MAXLIST) + ' Integers'); end.