скрыть

скрыть

  Форум  

Delphi FAQ - Часто задаваемые вопросы

| Базы данных | Графика и Игры | Интернет и Сети | Компоненты и Классы | Мультимедиа |
| ОС и Железо | Программа и Интерфейс | Рабочий стол | Синтаксис | Технологии | Файловая система |



Google  
 

TSortList - работа с отсортированным списком



Автор: Юрий Иванов

{ **** UBPFD *********** by delphibase.endimus.com ****
>> TSortList - работа с отсортированным списком

Класс для работы с отсортированным списком. Использует базовый класс TList.
Позволяет добавлять элементы в отсортированном порядке, производить
быстрый поиск элементов и очищать память указателей и память,
распределенную для элементов хранения.
Добавлены 1 свойство и 4 новых метода:
Свойство:
Compare - имя функции сравнения типа TListSortCompare.
Методы:
AddSort - позволяет добавлять элементы в список в отсортированном порядке.
Search - осуществляет быстрый поиск элемента в отсортированном списке (возвращает его номер или -1).
GetItem - возвращает указатель на найденный элемент, если элемент отсутствует, возвращается nil.
ClearAll - очищает память указателей и память, распределенную под хранение элементов Item.

Зависимости: Classes, SysUtils
Автор:       Юрий, i7@mail.ru, Тверь
Copyright:   Юрий Иванов (http://www.ivanovtver.chat.ru/sortlistr.zip)
Дата:        30 июля 2003 г.
***************************************************** }

{******************************************************************************
* SortList *
* -------- *
* Класс для работы с отсортированным списком. Использует базовый класс TList.*
* Позволяет добавлять элементы в отсортированном порядке и производить *
* быстрый поиск элементов. *
* Добавлены 1 свойство и 4 новых метода: *
* Свойство: Compare - имя функции сравнения типа TListSortCompare. *
* Смотри описание метода Sort в TList. *
* Имя функции должно быть назначено до выполнения методов*
* AddSort и Search. Если это не сделано, то генерируется *
* ошибка. *
* Методы: AddSort - позволяет добавлять элементы в List в *
* отсортированном порядке. *
* Search - осуществляет быстрый поиск элемента в *
* отсортированном списке. Item - указатель на искомый *
* элемент. Может содержать только "ключевые" значения, *
* используемые в функции сравнения. *
* Возврат - номер элемента в списке, начиная с 0. *
* Если элемент не найден, то возвращается отрицательное *
* значение (-1). *
* GetItem - возвращает указатель на найденный элемент *
* если элемент отсутствует, возвращается nil *
* ClearAll - очищает память указателей и память, *
* распределенную под хранение элементов Item *
* Внимание! Во избежание нарушения порядка сортировки, не пользуйтесь *
* совместно с новым AddSort методами Add и Insert, *
* оставшимися от TList. *
*******************************************************************************
* Может использоваться без ограничений. *
******************************************************************************* *
* Разработчик Иванов Ю. E-mail: i7@mail.ru *
* Информацию о других разработках автора можно посмотреть на странице *
* http://i7.da.ru *
* *
* декабрь 2000 г. - июль 2002 *
*******************************************************************************
Пример использования:
interface
...
type Tdat = record
     kod: integer;
     txt: string[50];
     num: double;
end;
...
var
    ldat: TSortList;
    dat: ^Tdat;
...
implementation
//*********************************************
function Sort_dat(i1,i2: Pointer): integer;
var
d1,d2: ^Tdat;
begin
    d1:=i1; d2:=i2;
    if d1^.kod < d2^.kod then Result:=-1
    else
      if d1^.kod > d2^.kod then Result:=1
      else
        Result:=0;
end;
//*********************************************
procedure ....
var
 d: Tdat;
 pos: integer;
begin
...
   // добавление элемента
        New(dat);
        dat^.kod:=kodd;
        dat^.txt:=st;
        dat^.num:=dob;
        ldat.AddSort(dat);
    end;
...
  // поиск элемента по "ключевым полям"
        d.kod:=8613;
        pos:=ldat.Search(@d);
        if pos < 0 then
          ShowMessage('элемент '+ IntToStr(d.kod) + ' не найден')
        else
        dat:=ldat.Items[pos];
...
  // получение элемента по "ключевым полям"
        d.kod:=8613;
        dat:=ldat.GetItem(@d);
        if dat = nil then
          ShowMessage('элемент '+ IntToStr(d.kod) + ' не найден')
...
  // очистка списка и памяти элементов
        ldat.ClearAll;
...
end;
...
initialization
  ldat:=TSortList.Create;
  ldat.Compare:=Sort_dat;
finalization
  ldat.Free;
end.
*********************************************************************}
unit Sortlist;

interface
uses Classes, SysUtils;

type
  TSortList = class(TList)
  private
    Ret: integer;
    ERR: byte;
    pcl, pcr: Pointer;
    FCompare: TListSortCompare;
    procedure SetCompare(Value: TListSortCompare);
    function SearchItem(Item: Pointer): integer;
    procedure QuickSearch(Item: Pointer; L, R: integer);
  public
    procedure AddSort(Item: Pointer);
    function Search(Item: Pointer): integer;
    procedure ClearAll;
    function GetItem(Item: Pointer): Pointer;
    property Compare: TListSortCompare read FCompare write SetCompare;
  end;
implementation
//*******************************************

procedure TSortList.ClearAll;
var
  i: integer;
  Item: Pointer;
begin
  if Count <> 0 then
    for i := 0 to Count - 1 do
    begin
      item := Items[i];
      try
        Dispose(Item);
      except
      end;
    end;
  Clear;
end;
//------------------------------------------------------

procedure TSortList.SetCompare(Value: TListSortCompare);
begin
  FCompare := Value;
end;
//-----------------------------------------------------------

procedure TSortList.QuickSearch(Item: Pointer; L, R: integer);
var
  K: Integer;
  P: Pointer;
begin
  ERR := 0;
  Ret := -1;
  pcl := Items[L];
  if Compare(Item, pcl) < 0 then
  begin
    Ret := L;
    ERR := 1;
    exit;
  end
  else if Compare(Item, pcl) = 0 then
  begin
    Ret := L;
    exit;
  end;
  pcr := Items[R];
  if Compare(Item, pcr) > 0 then
  begin
    Ret := R;
    ERR := 2;
    exit;
  end
  else if Compare(Item, pcr) = 0 then
  begin
    Ret := R;
    exit;
  end;
  //-----------------
  if R - L > 1 then
  begin
    K := (R - L) div 2;
    P := items[L + K];
    if Compare(Item, P) < 0 then
      QuickSearch(Item, L, L + K)
    else
    begin
      if Compare(Item, P) > 0 then
        QuickSearch(Item, L + K, R)
      else if Compare(Item, P) = 0 then
      begin
        Ret := L + K;
        exit;
      end;
    end;
  end
  else
  begin
    ERR := 1;
    ret := R;
  end;
end;
//----------------------------------------------------

function TSortList.SearchItem(Item: Pointer): integer;
begin
  if Count > 0 then
  begin
    QuickSearch(Item, 0, Count - 1);
    Result := Ret;
  end
  else
  begin
    Result := 0;
    ERR := 2;
  end;
end;
//------------------------------------------------

function TSortList.Search(Item: Pointer): integer;
begin
  if Addr(Compare) = nil then
  begin
    Error('Функция сравнения не назначена', -1);
    Result := -1;
    exit;
  end;
  Result := SearchItem(item);
  if ERR <> 0 then
    Result := -1;
end;
//-----------------------------------------

procedure TSortList.AddSort(item: Pointer);
var
  i: integer;
begin
  if Addr(Compare) = nil then
  begin
    Error('Функция сравнения не назначена', -1);
    exit;
  end;
  i := SearchItem(item);
  if (ERR = 0) or (ERR = 1) then
    Insert(i, item)
  else if ERR = 2 then
    Add(item);
end;
//-------------------------------------------------

function TSortList.GetItem(Item: Pointer): Pointer;
var
  i: integer;
begin
  i := Search(Item);
  if i = -1 then
    Result := nil
  else
    Result := Items[i];
end;
end.





Copyright © 2004-2016 "Delphi Sources". Delphi World FAQ




Группа ВКонтакте   Ссылка на Twitter   Группа на Facebook