
- •Тема 7. ХЕШИРОВАНИЕ
- •предпосылки
- •Идея алгоритма хеширования
- •Схема хеширования
- •Хеш-функция
- •Алгоритм разрешения конфликтов
- •Алгоритм размещения записей
- •Алгоритм поиска
- •Если ключ не число?
- •Хеш-таблица на основе массива связанных списков
- •массив связанных списков
- •Используемые типы
- •Поля и методы класса ТН
- •Метод create
- •При освобождении таблицы методом (THesh.Free) все записи считываются в StringGrid и освобождается память,
- •добавить новую запись метод Add(Inf:Tinf);
- •Чтение без удаления метод Read(key:Tkey):Tinf;
- •Чтение c удалением метод Readd(key:Tkey):Tinf;
- •метод Readd(key:Tkey):Tinf;
- •Чтение c удалением метод Readd(key:Tkey):Tinf;
- •Пример организации работы с классом THesh
- •Кнопка занести данные из StringGrid в хеш-таблицу
- •Кнопка добавить новую запись в хеш-таблицу
- •Кнопка прочесть и удалить запись с заданным ключом
- •Выдать и удалить хеш-таблицу
- •Преимущество рассмотренного метода заключается в том, что связанные хэш-таблицы никогда не переполняются, довольно
- •Другие способы хеширования
- •Перемешанная таблица
- •Метод блоков
- •Контрольные вопросы
- •Задача на экзамен
Хеш-таблица на основе массива связанных списков
Один из самых изящных способов разрешения конфликтов состоит в том, чтобы сохранять записи, отображаемые на одну позицию в связанные стеки. Для этого вводится массив из М указателей на связанные стеки
Можно и на массив бинарных деревьев поиска
Обычно выбирают М - простое число, немного большее чем предполагаемое количество записей.
Хеш-функцию выбираем в виде i:=Key mod M.
Работу с таблицей удобно организовать посредством класса ТН
07/02/19 |
11 |

массив связанных списков
H[0..M-1]
0 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Inf |
A |
|
|
|
Inf |
A |
|
|
Inf |
nil |
|
|
|
|
||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Inf |
A |
|
|
|
Inf |
nil |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
nil |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
… |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
M-2 |
|
|
|
Inf |
A |
|
|
|
Inf |
nil |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
M-1 |
|
|
|
Inf |
nil |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
07/02/19 |
12 |
Используемые типы
•Type
•Tkey=Word;
•Tinf=record
•Fio:string;
•key:Tkey;
•end;
•Tsel=^sel;
•sel=record
•inf:Tinf;
• A:Tsel;
•end;
•Ms=array[0..1] of Tsel;
•Tms=^Ms;
07/02/19 |
13 |
Поля и методы класса ТН
•THesh=class(Tobject)
• M,n:Word;
• sp,sp1:Tsel;
• H:Tms;
•Constructor create(M0:word);
•Destructor Free(var sgrid:Tstringgrid);
•Procedure Add(Inf:Tinf);
•Function Read(key:Tkey):Tinf; //без удаления
•Function Readd(key:Tkey):Tinf;//с удалением
•end;
07/02/19 |
14 |
Метод create
•Constructor THesh.create(M0:word);
•var i:word;
• |
begin |
Inherited |
create; |
• |
M:=M0; n:=0; |
//Количество записей n |
|
• |
Getmem(H,M*4); |
..//Размещаем М указателей |
|
• |
for i:=0 to M-1 do H[i]:=Nil; |
•end;
07/02/19 |
15 |
|
Метод Free(var sgrid:Tstringgrid); |
Destructor THesh.Free;// прочесть и удалить |
|
• |
var i,j:word; |
• |
begin j:=0; |
• |
for i:=0 to M-1 do begin |
• |
While H[i]<>Nil do |
• |
begin Inc(j); |
• |
sp:=H[i]; |
•SGrid.Cells[0,j]:=sp^.inf.Fio;
•SGrid.Cells[1,j]:=IntToStr(sp^.inf.key);
• |
H[i]:= H[i]^.A; |
• |
dispose(sp); |
• |
end; |
• |
end; |
• |
FreeMem(H,4*M); n:=0; |
• |
Inherited Free; |
•end;
07/02/19 |
16 |
При освобождении таблицы методом (THesh.Free) все записи считываются в StringGrid и освобождается память, выделенная под них, после этого освобождается память, выделенная под массив указателей, после этого освобождается память выделенная под сам объект.
Вместо записи в StringGrid легко организовать запись в файл или Memo.
07/02/19 |
17 |
добавить новую запись метод Add(Inf:Tinf);
•Procedure THesh.Add;
•begin
• |
i:=inf.key Mod M; |
• |
New(p); Inc(n); |
• |
p^.Inf:=Inf; |
• |
p^.A:=H[i]; |
• |
H[i]:=p; |
• |
end; |
07/02/19 |
18 |
Чтение без удаления метод Read(key:Tkey):Tinf;
•Function THesh.Read;
•begin
• |
i:=key mod M; |
• |
sp:=H[i]; |
• While (sp<>Nil) and (sp^.inf.key<>key) do
• |
sp:=sp^.A; |
• |
if sp<>Nil then Result:=sp^.inf |
• |
else ShowMessage('ключ не найден'); |
•end;
07/02/19 |
19 |
Чтение c удалением метод Readd(key:Tkey):Tinf;
•Procedure THesh.Readd;
• |
begin |
• |
i:=key mod M; |
• |
sp:=H[i]; |
•if sp=Nil then ShowMessage('ключ не найден')
• |
else |
•begin
• |
if sp^.inf.key=key //ключ в первой записи |
•then begin Result:=sp^.inf;
• |
H[i]:=H[i].A; dispose(sp); Dec(n); end |
•else
07/02/19 |
20 |