Binary search on an alphasorted TListView (Views: 101)


How to do a binary search on an alphasorted TListView


If you want to use a fast searching algorithm (binary search for example) the listview has to be sorted on the column you do the duplicate check on. If it is not sorted you have to use the listviews FindCaption or FindData method, which does a linear search. To sort a listview use its AlphaSort or CustomSort methods.

A binary search on a alphasorted listview for a caption would be something like this (untested!):

Function ListviewBinarySearch


listview to search, assumed to be sorted, must be <> nil.

item caption to search for, cannot be empty

returns the index of the found item, or the index where the item should be inserted if it is not already in the list. Returns True if there is an item with the passed caption in the list, false otherwise.

Uses a binary search and assumes that the listview is sorted ascending on the caption of the listitems. The search is case-sensitive, like the default alpha-sort routine used by the TListview class.

We use the lstrcmp function for string comparison since it is the function used by the default alpha sort routine. If the listview is sorted by another means (e.g. OnCompare event) this needs to be changed, the comparison method used must always be the same one used to sort the listview, or the search will not work!

Error Conditions: none
Created: 31.10.99 by P. Below

function ListviewBinarySearch(listview: TListview; const Item: string; var index:
  Integer): Boolean;
  first, last, pivot, res: Integer;
  Assert(Length(item) > 0);
  Result := false;
  index := 0;
  if listview.items.count = 0 then
  first := 0;
  last := listview.items.count - 1;
    pivot := (first + last) div 2;
    res := lstrcmp(PChar(item), Pchar(listview.items[pivot].caption));
    if res = 0 then
      { Found the item, return its index and exit. }
      index := pivot;
      result := true;
    else if res > 0 then
      { Item is larger than item at pivot }
      first := pivot + 1;
      { Item is smaller than item at pivot }
      last := pivot - 1;
    last < first;
  index := first;

<< Back to main page