52704.fb2 Фундаментальные алгоритмы и структуры данных в Delphi - читать онлайн бесплатно полную версию книги . Страница 111

Фундаментальные алгоритмы и структуры данных в Delphi - читать онлайн бесплатно полную версию книги . Страница 111

type

TtdHashTableChained = class

{хеш-таблица, в которой для разрешения конфликтов используется связывание}

private

FChainUsage : TtdHashChainUsage;

FCount : integer;

FDispose : TtdDisposeProc;

FHashFunc : TtdHashFunc;

FName : TtdNameString;

FTable : TList;

FNodeMgr : TtdNodeManager;

FMaxLoadFactor : integer;

protected

procedure htcSetMaxLoadFactor(aMLF : integer);

procedure htcAllocHeads(aTable : TList);

procedure htcAlterTableSize(aNewTableSize : integer);

procedure htcError(aErrorCode : integer;

const aMethodName : TtdNameString);

function htcFindPrim(const aKey : string;

var aInx : integer; var aParent : pointer): boolean;

procedure htcFreeHeads(aTable : TList);

procedure htcGrowTable;

public

constructor Create(aTableSize : integer;

aHashFunc : TtdHashFunc; aDispose : TtdDisposeProc);

destructor Destroy; override;

procedure Delete(const aKey : string);

procedure Clear;

function Find(const aKey : string; var aItem : pointer): boolean;

procedure Insert(const aKey : string; aItem : pointer);

property Count : integer read FCount;

property MaxLoadFactor : integer

read FMaxLoadFactor write htcSetMaxLoadFactor;

property Name : TtdNameString read FName write FName;

property ChainUsage : TtdHashChainUsage

read FChainUsage write FChainUsage;

end;

Мы объявили небольшой перечислимый тип TtdHashChainUsage для указания того, выполняется ли вставка элементов в начало или в конец связного списка. Класс содержит свойство ChainUsage, которое указывает, какой метод следует использовать.

---------

Свойство MaxLoadFactor служит для выполнения еще одной настройки. Оно определяет среднюю максимальную длину связных списков, хранящихся в каждой из ячеек. Если средняя длина связных списков становится слишком большой, класс увеличит внутреннюю хеш-таблицу, используемую для хранения элементов, и повторит их вставку.

Использование свойства MaxLoadFactor может оказаться затруднительным. Какое значение оно должно иметь? Вспомните, что его можно считать равным средней длине связных списков, хранящихся в каждой из ячеек. Если придерживаться правила, применяемого для линейного зондирования, в соответствии с которым коэффициент загрузки выбирается так, чтобы для обнаружения промаха при поиске требовалось в среднем пять зондирований, то значение MaxLoadFactor должно быть равно пяти.

---------

Однако необходимо учитывать еще одно соображение. При каждом зондировании выполняется сравнение искомого ключа с ключом элемента в хеш-таблице. Если сравнение занимает длительное время, как при поиске длинной строки, значение MaxLoadFactor должно быть меньше. Если сравнение выполняется значительно быстрее (например, в случае поиска короткой строки или целого числа), значение MaxLoadFactor может быть больше. Как и в случае любых настроек, чтобы добиться наилучших результатов, потребуется провести некоторый объем экспериментов.

Если внимательно присмотреться к коду, то мы увидим, что в нем используется хорошо известный нам класс TtdNodeManager (как именно - будет показано вскоре). Конструктор Create, как и TList, будет выделять один экземпляр этого класса. Деструктор Destroy будет освобождать оба эти экземпляра.

Листинг 7.12. Конструктор и деструктор класса TtdHashTableChained

constructor TtdHashTableChained.Create(aTableSize : integer;

aHashFunc : TtdHashFunc;

aDispose : TtdDisposeProc);

begin

inherited Create;