unit uutlAlgorithm; {$mode objfpc}{$H+} interface uses Classes, SysUtils, uutlInterfaces; type ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// generic TutlQuickSort = class(TObject) public type IList = specialize IutlList; IComparer = specialize IutlComparer; private class procedure DoSort( aList: IList; aComparer: IComparer; aLow: Integer; aHigh: Integer); public class procedure Sort( aList: IList; aComparer: IComparer); end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// generic TutlBinarySearch = class(TObject) public type IList = specialize IutlReadOnlyList; IComparer = specialize IutlComparer; private class function DoSearch( aList: IList; aComparer: IComparer; const aMin: Integer; const aMax: Integer; constref aItem: T; out aIndex: Integer): Boolean; public class function Search( aList: IList; aComparer: IComparer; constref aItem: T; out aIndex: Integer): Boolean; end; implementation ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TutlQuickSort////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// class procedure TutlQuickSort.DoSort(aList: IList; aComparer: IComparer; aLow: Integer; aHigh: Integer); var lo, hi: Integer; p, tmp: T; begin repeat lo := aLow; hi := aHigh; p := aList.GetItem((aLow + aHigh) div 2); repeat while (aComparer.Compare(p, aList.GetItem(lo)) > 0) do lo := lo + 1; while (aComparer.Compare(p, aList.GetItem(hi)) < 0) do hi := hi - 1; if (lo <= hi) then begin tmp := aList.GetItem(lo); aList.SetItem(lo, aList.GetItem(hi)); aList.SetItem(hi, tmp); lo := lo + 1; hi := hi - 1; end; until (lo > hi); if (hi - aLow < aHigh - lo) then begin if (aLow < hi) then DoSort(aList, aComparer, aLow, hi); aLow := lo; end else begin if (lo < aHigh) then DoSort(aList, aComparer, lo, aHigh); aHigh := hi; end; until (aLow >= aHigh); end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// class procedure TutlQuickSort.Sort(aList: IList; aComparer: IComparer); begin DoSort(aList, aComparer, 0, aList.GetCount-1); end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TutlBinarySearch/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// class function TutlBinarySearch.DoSearch(aList: IList; aComparer: IComparer; const aMin: Integer; const aMax: Integer; constref aItem: T; out aIndex: Integer): Boolean; var i, cmp: Integer; begin if (aMin <= aMax) then begin i := aMin + Trunc((aMax - aMin) / 2); cmp := aComparer.Compare(aItem, aList.GetItem(i)); if (cmp = 0) then begin result := true; aIndex := i; end else if (cmp < 0) then result := DoSearch(aList, aComparer, aMin, i-1, aItem, aIndex) else if (cmp > 0) then result := DoSearch(aList, aComparer, i+1, aMax, aItem, aIndex); end else begin result := false; aIndex := aMin; end; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// class function TutlBinarySearch.Search(aList: IList; aComparer: IComparer; constref aItem: T; out aIndex: Integer): Boolean; begin result := DoSearch(aList, aComparer, 0, aList.GetCount-1, aItem, aIndex); end; end.