Programmirovanie_i_osnovyi_algo
.pdf// |
должны быть ал фа витно-упорядоченными по ключам |
||||||||
void |
Round( |
|
|
|
|
|
|
|
|
|
±nt |
root |
) |
// Корень дерева |
|
||||
{ |
±£( size |
< root |
) |
|
|
|
|
||
|
|
Выход из рекурсии |
|
||||||
|
{ |
|
|
|
// |
!!! |
|
||
|
} |
|
|
|
|
|
|
|
|
|
Round( |
2*root ); |
// |
Обойти вершины левого |
поддерева |
||||
|
// |
Приписать корню очередную по алфавиту строку таблицы |
|||||||
|
±f( |
fscanf( |
pStructFilelnp, |
"%8s%62s", |
|
||||
|
|
рТаЫе[ |
root-1 |
].key, |
рТаЫе[ root-1 ],data |
) ! =2 ) |
|||
|
{ |
printf( |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||
"\n |
Ошибка 120. |
Ошибка чтения строки таблицы \п" |
); |
||||||
|
|
exit ( 120 |
); |
|
|
|
|
||
|
} |
|
|
|
|
|
|
|
|
|
Round( |
2*root+l ); |
// |
Обойти вершины правого поддерева |
return/
//Бинарный (логарифмический) поиск в таблице, подготовленной
//в форме алфавитно-упорядоченного двоичного дерева
void. LogariphmSearch |
( |
|
|
|
// Ключ для поиска |
строки в таблице |
|||
сЪаг |
Keyword [ |
] , |
|
|
±nt |
&found, |
|
// |
1 - нашли |
±Tib |
Scline ) |
|
// |
Индекс найденной строки |
{ |
i, |
// |
Индекс вершины дерева |
|
int |
||||
|
EndTab; |
|
// 1 - достигнут конец таблицы |
//Подготовка к поиску found = 0; EndTab = 0;
//Поиск
i = 1;
while ( ! found && .'EndTab )
{
±f( !strcmp( Keyword, pTable[ i-1 ] . key ) )
{//Нашли
found = 1; line = i-1;
}
else
{//Шаг вперед по таблице
±f( strcmp( Keyword, pTable [ i-1 ] , key ) < 0 )
{
i = 2*i/
}
300
else |
|
|
{ |
= |
2*i-i-l/ |
1 |
||
} |
|
|
EndTab |
= |
(i > size ) , |
|
return; |
|
|
|
|
|
|
|
|
|
|
// |
Преобразование |
|
|
символа |
|
ключа - строчная |
латинская |
буква, |
|||
// |
цифра |
или |
пробел |
- в |
его порядковый |
номер |
(целое |
число) |
|||
±п\t |
Kod( |
|
symbol |
) |
// |
Порядковый номер |
символа |
|
|||
( |
char |
|
// |
Преобразуемый |
символ |
|
|||||
switch ( |
S3/mbol |
) |
|
|
|
|
|
|
|||
|
|
|
|
|
|
|
|||||
|
{ |
' a |
': |
return |
0; |
|
|
|
|||
|
case |
|
|
|
|||||||
|
case |
'b' |
|
: |
return |
1; |
|
|
|
||
|
case |
'c' |
|
: |
return |
2; |
|
|
|
||
|
case |
d' |
: |
return |
3; |
|
|
|
|||
|
case |
'e' |
|
: |
return |
4; |
|
|
|
||
|
case |
f |
|
: |
return |
5; |
|
|
|
||
|
case |
g' |
: |
return |
6; |
|
|
|
|||
|
case |
h'; |
return |
7; |
|
|
|
||||
|
case |
'i ': return |
8; |
|
|
|
|||||
|
case |
J'.• |
return |
9; |
|
|
|
||||
|
case |
;c' : |
return |
10 |
|
|
|
||||
|
case |
1 ' : |
return |
11 |
|
|
|
||||
|
case |
m ': |
return |
12 |
|
|
|
||||
|
case |
n |
|
': |
return |
13 |
|
|
|
||
|
case |
o' |
: |
return |
14 |
|
|
|
|||
|
case |
p': |
|
|
return |
15 |
|
|
|
||
|
case |
q': |
: |
return |
16 |
|
|
|
|||
|
case |
r' |
return |
17 |
|
|
|
||||
|
case |
s' |
: |
return |
18 |
|
|
|
|||
|
case |
t': |
return |
19 |
|
|
|
||||
|
case |
u': |
return |
|
20 |
|
|
|
|||
|
case |
V* : |
return |
21 |
|
|
|
||||
|
case |
w' |
: |
return |
22 |
|
|
|
|||
|
case |
X' |
|
: |
return |
|
23 |
|
|
|
|
|
case |
y |
' |
: |
return |
|
24 |
|
|
|
|
|
case |
z |
|
': |
return |
|
25 |
|
|
|
|
|
case |
0' |
: |
return |
|
26 |
|
|
|
||
|
case |
1 ': |
return |
|
27 |
|
|
|
|||
|
case |
2': |
: |
return |
|
28 |
|
|
|
||
|
case |
3' |
return |
|
29 |
|
|
|
|||
|
case |
4 ' : |
return |
|
30 |
|
|
|
|||
|
case |
5' |
: |
return |
|
31 |
|
|
|
||
|
case |
6' |
: |
return |
|
32 |
|
|
|
||
|
case |
7': |
return |
|
33. |
|
|
|
301
case |
'8*: |
return |
34; |
case |
'9': |
return |
35; |
case |
' ': return |
36; |
|
|
dLefaul t: |
|
|
|
|
|
|
||
"\n |
Ошибка |
printf( |
поиска |
содержит недопустимый |
символ. |
\п" |
||||
130. |
Ключ |
|||||||||
"\п |
Ключ |
может |
содержать |
толька строчные |
латинские |
буквы, |
" |
|||
" цифры |
и |
пробел |
\п" |
) ; |
; |
|
|
|
|
|
|
|
|
exit |
( 130 |
) |
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
return |
|
-1; |
|
|
// |
Этот оператор |
не будет |
|
|
|
|
|
|
|
|
// |
выполняться |
|
|
}
// |
Хэш-функция |
ключа "KeyWord" из "LKEY-1" символа |
для |
(символ - |
|||
// |
строчная |
латинская |
буква, |
цифра |
или пробел) |
таблицы |
|
// |
из size |
строк |
// Возвращает |
индекс строки |
таблицы |
||
int |
Hash( |
|
//Ключ
char
{ |
unsigned. |
|
±nt |
|
|
|
|
|
|
|
|
|
|
|
|
|
||
|
|
|
|
|
// |
|
Индекс |
|
символа |
|
в |
ключе |
||||||
|
±nt |
|
|
I Key; |
0; |
|
|
|
|
|||||||||
|
|
|
|
ih |
= |
|
// |
|
Значение |
|
хэш-функции |
|||||||
|
// |
Вычисление |
|
индекса |
|
строки |
таблицы |
|
|
|
||||||||
|
for( |
IKey |
= |
0; |
I Key |
< |
strlen |
( |
KeyWord |
) |
; |
IKey-h-h ) |
||||||
|
{ |
ih |
= |
ih |
* |
37 |
-f Kod( |
KeyWordf |
IKey |
] |
) ; |
|||||||
|
|
|||||||||||||||||
|
} |
ih |
= |
ih |
% |
|
size; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return |
ih; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// |
Начальная |
|
подготовка |
|
хэш-таблицы |
|
|
|
|
|
||||||||
void |
BeginTable |
|
( |
|
|
|
|
|
Указатель |
на |
файл |
ввода |
||||||
|
char |
|
|
*pFileInp,// |
|
|
||||||||||||
|
int |
|
|
|
ТаЫеЬеп |
|
) / |
/ Число |
вводимых |
|
строк |
|||||||
{ |
int |
|
|
i , |
|
|
|
// |
|
Индекс |
|
строки |
|
таблицы |
||||
|
|
|
|
|
|
|
|
|
||||||||||
|
|
|
|
line, |
|
|
|
// |
|
Номер |
текуш,ей |
|
строки |
|||||
|
// |
|
|
found; |
|
|
// |
|
1 |
- найдена |
позиция |
вставки |
||||||
|
Заносимое |
|
слово |
[ |
LKEY |
]; |
|
|
|
|
|
|
||||||
|
char |
|
Keyword |
|
|
|
|
|
|
|||||||||
|
// |
Инициализация |
|
таблицы |
нуль-символ |
а ми |
|
|
||||||||||
|
£ог( |
i |
= |
О; |
i |
< |
size; |
|
i++ |
) |
|
|
|
|
|
|
||
|
{ |
£or( |
|
int |
il |
|
|
0; |
il |
|
< |
LKEY; |
il++ |
) |
|
|
||
|
|
|
|
= |
|
|
|
302
рТаЫе[ |
i |
] . key |
[ 11 |
] |
= |
'\0'; |
fox:( int 12 |
= |
0; 12 |
< LDATA; |
12 + + ) |
||
pTablef |
1 |
] .data[ |
12 |
] |
= |
'\0'; |
}
// |
Отметка |
строк |
таблицы |
как |
свободных |
|||
for( |
1 = О; |
1 |
< |
size; |
1++ |
) |
|
|
( |
pTablef |
1 |
J.keyf |
О ] |
^ |
' |
'/ |
|
|
}
//Открытие файла для чтения
pStructFllelnp |
|
== OpenFlle( |
pFllelnpr |
|
|
|
"г", 140 |
) ; |
|
||||||||||||
// |
Занесение |
в |
таблицу |
исходных |
строк |
|
|
) |
|
|
|
|
|||||||||
for( |
line |
= |
0; |
line |
< |
TableLen; |
|
llne++ |
|
|
|
строк |
|
||||||||
{ |
|
|
|
|
|
|
// |
Цикл |
чтения |
исходных |
|
|
|||||||||
|
±f( |
|
fscanf( |
pStructFllelnp, |
|
|
" |
%s", |
|
|
Keyword |
) |
!= |
1 ) |
|||||||
|
{ |
|
printf( |
"\n |
Ошибка |
150. |
Ошибка |
|
|
чтения |
ключа |
из" |
|||||||||
|
|
|
|
|
|||||||||||||||||
|
} |
|
|
|
" строки |
с |
индексом |
|
%d |
\п", line |
) ; |
|
|||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// |
Поиск |
индекса |
'1' |
строки |
таблицы |
|
для |
ее |
|
заполнения |
||||||||||
|
found |
= |
О; |
|
|
// |
|
Пока |
индекс |
|
не |
|
|
найден |
|
|
|
||||
|
while( |
/found |
) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||
|
{ |
|
±f( |
pTablef |
|
1 |
].key[ |
|
0 ] |
== |
' |
|
' |
) |
|
|
|
|
|||
|
|
|
|
|
|
|
|
|
|
||||||||||||
|
|
|
{ |
|
|
|
// |
Индекс |
найден |
|
|
|
|
|
|
|
|||||
|
|
|
|
found |
- |
1; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
else |
|
|
|
// |
|
Конфликт |
- шаг |
|
|
по |
таблице |
|
||||||
|
|
|
{ |
1++; |
1 |
1 |
? |
|
|||||||||||||
|
|
|
|
= ( |
> |
( |
slze-1 |
|
) |
0: |
1 ) |
; |
|
|
|||||||
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// |
Чтение |
данного |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||
|
±f( |
|
fscanf( |
pStructFllelnp, |
|
|
" |
%s", |
|
|
|
|
|
|
|
||||||
|
|
|
pTablef |
1 |
] .data |
) |
!= |
1 |
) |
|
|
|
|
|
|
|
|
|
|||
|
{ |
|
printf( |
"\n |
Ошибка |
160. |
Ошибка |
|
чтения |
ключа |
из" |
||||||||||
|
|
|
|
||||||||||||||||||
|
|
|
|
|
" |
строки |
с |
индексом |
|
%d |
|
\л", line |
) / |
|
|||||||
|
|
|
exlt |
( |
160 |
) |
; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// |
Занесение |
|
ключа |
в |
строку |
"1" |
таблицы |
|
|
|
|
|||||||||
|
strcpyi |
pTablef |
|
1 |
].key, |
|
KeyWord |
) |
/ |
|
|
|
|
|
|
//Закрытие файла ввода
CloseFlle( |
pStructFllelnp, |
pFllelnp, |
170 ) ; |
геЬмтсп;
303
}
// Поиск |
В |
хэш-таблице |
|
|
|
|
|
|
|
void |
HashSearch( |
для |
|
поиска |
|
|
|
|
|
// Ключевое слово |
], |
|
|
|
|
||||
char |
|
Keyword |
[ |
1 - |
нашли |
|
|
|
|
±nt |
|
бе founds |
// |
|
строки |
в таблице |
|||
±nt |
|
&11пе |
) |
// |
Индекс |
найденной |
|||
{ |
|
|
|
|
|
|
|
|
|
±nt |
|
1, |
|
// |
Индекс |
строки |
|
таблицы |
|
|
|
EndTah; |
|
// |
1 - достигли |
свободной |
строки |
//Подготовка к поиску
found = О; EndTab = О; i = Hash( KeyWord ) ;
//Поиск в таблице
while ( ( .'found ) && ( .'EndTab ) )
{
±f( pTablel |
1 |
J.keyf |
0 ] |
== |
' ' |
) |
|
|
{ |
|
|
// |
Достигли |
свободной |
строки |
||
EndTab |
= |
1; |
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
|
±£( ! strcmp |
( pTablef |
1 |
] . key, |
KeyWord ) ) |
||||
{ |
|
|
// |
Нашли |
|
|
|
|
found |
= |
1; |
line |
= i; |
|
|
}
else
{// Шаг no таблице
i++; i = ( i > ( size-1 |
) ? 0: i ) ; |
}
}
}
retujni/
|
Для файла исходных данных, имеющего вид |
call |
вызов |
type |
тип |
word |
слово |
work |
работа |
был |
получен следующий файл результатов: |
|
Состояние та блицы: |
call |
вызов |
type |
тип |
word |
слово |
work |
работа |
304
Тестирование |
|
последовательного |
поиска |
||||||||
Результаты |
поиска |
для |
в |
ключевого |
слова: |
and |
|||||
Строка |
с ключом |
"and" |
таблице |
не |
найдена. |
||||||
Результаты |
поиска |
для |
|
ключевого |
слова: |
word |
|||||
Индекс |
строки |
в |
таблице: |
2. |
Найденная |
|
строка: |
||||
word |
слово |
|
|
|
|
|
|
|
|
|
|
|
|
Состояние |
та блицы: |
|
|
|
|||||
word |
|
слово |
|
|
|
|
|
|
|
|
|
type |
тип |
|
|
|
|
|
|
|
|
|
|
work |
работа |
|
|
|
|
|
|
|
|
||
call |
|
вызов |
|
|
|
|
|
|
|
|
|
Тестирование |
|
логарифмического |
поиска |
|
|||||||
Результаты |
поиска |
для |
в |
ключевого |
слова: |
and |
|||||
Строка |
с ключом |
"and" |
таблице |
не |
найдена. |
||||||
.Результаты |
поиска |
для |
|
ключевого |
слова: |
word |
|||||
Индекс |
строки |
в |
таблице: |
О. Найденная |
|
строка: |
|||||
word |
слово |
|
|
|
|
|
|
|
|
|
|
|
|
Со стояние |
та блицы: |
|
|
|
|||||
call |
|
вызов |
|
|
|
|
|
|
|
|
|
type |
тип |
|
|
|
|
|
|
|
|
|
|
Тестирование |
|
хэш-поиска |
|
|
|
|
|||||
Результаты |
поиска |
для |
|
ключевого |
слова: |
work |
|||||
Строка |
с ключом |
"work" |
|
в таблице |
не |
найдена. |
|||||
Результаты |
поиска |
для |
|
ключевого |
слова: |
type |
|||||
Индекс |
строки |
в |
таблице: |
2. |
Найденная |
|
строка: |
||||
type |
тип |
|
|
|
|
|
|
|
|
|
17.3. Логарифмический (бинарный) поиск
Кардинальное повышение эффективности поиска в таблице достигается полным пересмотром алгоритма поиска аналогично то му, как это было ранее в сложных алгоритмах сортировки массивов.
Пример. В реальных словарях, например в англо-русском сло варе, человек быстро находит нужные сведения, используя их упо рядоченность по алфавиту. Указанный подход и использован при
305
логарифмическом (с помощью двоичного дерева) поиске в таблице. Если исходную таблицу (словарь) предварительно подготовить
в форме двоичного дерева так, чтобы ключи левого поддерева были раньше по алфавиту, чем ключ корня, а ключи правого поддерева - позже, то число обращений к таблице для сравнения с заданным ключевым словом не может превышать log^isize). При этом, после каждого обращения к таблице, область поиска сокращается в общем случае примерно в два раза.
Начальная подготовка таблицы в форме двоичного дерева.
Исходные данные при заполнении таблицы перед чтением должны быть упорядочены по алфавиту для ключевых слов. Это легко обес печить, используя рассмотренные выше способы сортировки масси вов.
Пусть, например, читаемые данные содержат в каждой отдель ной строке информацию для заполнения одной строки таблицы, причем они отсортированы по ключам по не убыванию (size=\0):
А |
Data |
for |
string |
0 |
|
В |
Data |
for |
string |
1 |
|
С |
Data |
for |
string |
2 |
|
D |
Data |
for |
string |
3 |
|
Е |
Data |
for |
string |
4 |
|
F |
Data |
for |
string |
5 |
|
G |
Data |
for |
string |
6 |
|
Н |
Data |
for |
string |
7 |
|
I |
Data |
for |
string |
8 |
(size-1) |
J |
Data |
for |
string |
9 |
Двоичное дерево строится, как это было ранее рассмотрено, с использованием рекуррентного подхода (см. рис. 57). Для нашего примера после начальной подготовки двоичное дерево должно иметь вид, показанный на рис. 98.
Соответственно этому алгоритму можно записать рекуррент ную функцию Round и использующую ее функцию InpTabLog для начального заполнения и подготовки таблицы, прототипы и опреде ления которых содержатся в вышеприведенной программе. Обрати
те внимание на то, что функция |
Round является вспомогательной |
||
для функции InpTabLog. |
|
|
|
Бинарный |
(логарифмический) |
поиск в таблице, |
подготов |
ленной в форме |
двоичного дерева. |
Идея поиска состоит |
в следую |
щем. |
|
|
|
1. Исходный ключ сравнивается с ключом, соответствующим корню дерева (номер соответствующей вершины дерева / = 1, а ин декс элемента массива - (/ - 1) ). Если при этом ключи совпадают, то нужная строка найдена {found = 1), ее индекс line = i - 1 и поиск за-
306
вершен.
} 2 |
]\ |
/ / |
3 |
D |
|
|
1 |
В |
F |
н |
J |
А/ Лс- |
-ЕV |
|
|
10
Первые слова по алфавиту (A-B-C-D-E-F) присваиваются левому поддереву
Последние слова по алфавиту (H-I-J) присваиваются правому поддереву
Среднее слово по алфавиту (G) присваивается корню.
Аналогично заполняются левые и правые поддеревья для частичных корней
Рис. 98. Двоичное дерево после начального заполнения
2. Если поиск не завершен, то определяется поддерево для продолжения поиска путем сравнения KeyWord < рТаЫо[ /-1 ].кеу. При положительном итоге необходимо вести поиск в левом подде реве и номер следующей вершины / = /*2. При выполнении же про тивоположного условия KeyWord > рТаЫе[ /-1 ].кеу, поиск следует вести в правом поддереве и номер следующей вершины дерева / = /*2+1.
3. При выполнении условия i > size (вершину / дерево не со держит) поиск следует прекратить, так как строка с ключевым сло
вом KeyWord |
отсутствует {EndTab = 1 w found = 0). Иначе - выполня |
|
ется переход к п. 1 с новым значением /, соответствующим |
корню |
|
левого или правого поддерева. |
|
|
Легко заметить, что после каждого сравнения KeyWord |
с клю |
|
чом рТаЫе[ |
/-1 ].кеу область поиска сокращается примерно |
в два |
раза и среднее число обращений к таблице (средняя длина поиска) составляет 1^^.,, =\og^{size), что существенно эффективнее, чем при по следовательном поиске.
307
в соответствии со сказанным, прототип, определение функции LogariphmSearch и пример ее вызова имеют вид, показанный в про грамме из подразд. 17.2.
17.4. Поиск с использованием перемешанной таблицы (хэш-таблицы)
при поиске с использованием хэш-таблицы используется ор ганизация данных в виде массива. Основная идея поиска состоит в преобразовании заданного ключа Key Word в индекс Hash( Key Word ) соответствующей строки в таблице. Поэтому такой способ поиска иногда называют поиском с преобразованием ключей (рис. 99).
рТаЫе
Keyword |
Hash(KeyWord) |
|
|
Индекс строки в |
|
Исходный |
таблице с |
|
key= Keyword |
|
|
ключ |
|
|
|
Size-1 |
|
|
Ключ (key) |
Данное (data) |
Рис. 99. Хэш-поиск в таблице
Основная трудность преобразования ключей состоит в том, что множество возможных значений ключей намного обширнее, чем множество индексов строк в таблице. Так, например, если ключ со держит восемь символов, в качестве которых используются строч ные латинские буквы, цифры и пробел (всего 37 возможных значе ний каждого символа в ключе), то всего имеется 37^ возможных значений ключей, что, естественно, во много раз превышает реаль ный размер таблицы size. Из сказанного следует, что функция Hash является отображением "много в один".
Идея поиска с использованием хэил-таблицы состоит в сле дующем. Первый этап в операции поиска - вычисление соответст вующего индекса Hash{ KeyWord ) в таблице, а второй - очевидно необходимый этап - проверка, действительно ли элемент с ключом KeyWord находится в таблице в строке с индексом Hash( KeyWord ).
При этом сразу же возникают два вопроса.
308
1. Какую функцию Hash( KeyWord ) следует использовать?
2. Как поступать в ситуации, когда функция Hash{ KeyWord ) не дает местонахождения нужного элемента (! много ключей дают одинаковый индекс)?
Ответ на второй вопрос заключается в том, что нужно исполь зовать какой-то метод для получения нового индекса в таблице, а если и там нет нужного элемента, то следующего индекса и т.д. По
добный случай, когда |
в строке Hash{ KeyWord ) находится другой |
||||
ключ, а не ключ KeyWord^ называется конфликтом, |
а задача получе |
||||
ния альтернативных индексов li^зыв2iQTCЯ разрешением |
конфликтов. |
||||
Выбор функции |
преобразования. |
Основное |
требование |
к хо |
|
рошей функции преобразования Hash{ |
KeyWord |
) состоит |
в том, |
чтобы она распределяла ключи как можно более равномерно по шкале значений индексов. Разумеется, она должна также эффектив но вычисляться, т.е. состоять из очень небольшого числа основных арифметических действий.
Пусть ih определяет порядковый номер ключевого слова KeyWord во множестве всех возможных значений ключей и вычисляется следующим образом:
unsigned. |
±nt |
|
|
|
|
|
|
|
|
|
Int |
|
I Key; |
// |
Индекс |
|
символа |
в |
ключе |
||
|
ih |
= О; |
// |
Значение |
хэш-функции |
|||||
// |
Вычисление |
индекса |
|
строки |
|
таблицы |
|
|
||
for( |
IKey |
= 0; |
I Key |
< |
strlen |
( |
KeyWord |
) |
; IKey-h-h ) |
{
ih = ih * 37 + Kod( KeyWord[ IKey ] ) ;
}
ih = ih % size;
Врезультате вычислений ih получает значение из диапазона 0-
36.К сожалению, величина ih существенно превышает максимально допустимое целое значение (2'^-1 или 2^'~1). По этой причине функцию Hash{ KeyWord ) следует построить несколько иначе — вы числение
ih = ih % size;
перенести в блок цикла. Прототип полученной таким образом хэшфункции и ее определение приведены в примере программы в подразд. 17.2. Функция Hash{ KeyWord ) также является вспомогатель ной и используется при хэш-поиске. Эта функция обладает тем свойством, что значения ключей равномерно распределяются во всем интервале индексов строк таблицы. Исследованиями показано, что для большей равномерности распределения желательно, чтобы
309