Хэш функц
Хэш
засварлахЭнэ хайлтын арга нь түлхүүр утганд арифметик үйлдлээр хувиргалт хийн өгөгдөл байрлах хүснэгтийн хаягийг гарган авч шууд ханддаг.
Хеш хаяглал нь түлхүүрийн утга тодорхой биш, ерөнхий тохиолдолд энгийн энэ арга дээр үндэслэгддэг
Үндсэн асуудал:
Хадгалсан элементүүдийн хувьд дараах үйлдлүүдийг хийдэг.
add new element | Шинэ элемент нэмэх |
delete element | Элемент устгах |
search a element by key | Элементийг түлхүүрээр хайх |
Эрэмбэлээгүй массив буюу Unsorted array/
Элементүүдийг массивт эрэмбэлэлгүйгээр хадгалсанаар:
add | Хамгийн сүүлийн элемент болгож нэмэх |
delete | Устгах мэдээллээ олоход Удаан, Нүдийг дүүргэхэд Хурдан |
search | Дараалсан хайлт Удаан |
Эрэмбэлсэн массив буюу Sorted array
Элементүүдийг массивт эрэмбэтэйгээр хадгалсанаар
add | Элементийг тохирох байранд нь оруулах. Элементүүдийг шилжүүлэх үйлдэл хийдэг тул Удаан |
delete | Устгасны дараа хоосон үлдсэн зайг хэрхэн дүүргэх вэ гэсэн асуудал гардаг. Элементүүдийг шилжүүлдэг тул Удаан |
search | Хоёртын хайлт Хурдан |
Холбоост жагсаалт
add | Нэг л зангилаа руу ханддаг тул Хурдан |
Delete | Устгасны дараа холбоосыг хэвээр үлдээхэд Хурдан боловч тухайн устгах зангилааг хайж олоход Удаан |
search | Дараалсан хайлт Удаан O(n) �(Холбоост жагсаалт ашигласан үед элементүүд нь эрэмбэлэгдсэн байсан ч Хоёртын хайлтыг ашиглах боломжгүй юм.) |
Хүснэгт байдалтай массив буюу хеш хүснэгт
Элементүүдийг индекс нь түлхүүрийг илэрхийлэх маш том массивт хадгалсан үед:
add – Маш хурдан
delete - Маш хурдан
search - Маш хурдан
Гэвч энэ нь маш их санах ойг зарцуулна. Байх боломжгүй.
Хеш функц
Энэ нь түлхүүрийг тухайн хязгаар доторх индекс рүү чиглүүлдэг. Зорилтот шаардлагууд: Тооцоолоход хялбар ба хурдан байх Тархсан байсан ч зөрчил үүсэх магадлал маш их тул зайлсхийх
function Hash(key: KeyType): integer; Hash гэдэг функц байна гэж төсөөлье. Энэ нь 1000 элементийн түлхүүр буюу key-ыг 0..999 гэсэн бүхэл тоо руу чиглүүлдэг. (Ингэхдээ 2 ялгаатай түлхүүрт ижил дугаар олгодоггүй.) Perfect Hash function-тай Хэш хүснэгт:
Доорх боломжыг олгохоор индексийг үүсгэдэг функцыг perfect буюу төгс функц гэдэг.
add – Маш хурдан O(1)
delete - Маш хурдан O(1)
search - Маш хурдан O(1)
Төгс хеш функц гэдэг нь түлхүүр бүрт ялгаатай утга буюу индексийг боловсруулж өгдөг.
Гэвч энэхүү функцыг загварчлахад маш хүндрэлтэй (боломжит түлхүүрийн хэмжээ нь их үед)
Хуваах арга:
Түлхүүрийн тоо n-ээс их m тоог сонгоно. Хаяглалын зөрчилийг багасгахын тулд m анхны тоо байх шаардлагатай. Эндээс H функцыг H(k) = k(mod M) гэж тодорхойлдог. Хэрэв түлхүүр нь тоон утгаар өгөгдсөн бол функцад шууд ашиглана. Харин түлхүүр нь тэмдэгт мөрөөр өгөгдвөл түүнийг эхлээд тоон утгаар илэрхийлэх шаардлагатай.
Зөрчил:
Ерөнхийдөө зөрчилөөс зайлсхийж чаддаггүй Collision resolution – 2 ялгаатай түлхүүр ижил тоогоор илэрхийлэгдэх явдал хэр их тохиолдож байгаа нь.
H(‘0012345’) = 134 H(‘0033333’) = 67 H(‘0056789’) = 764 … H(‘9903030’) = 3 H(‘9908080’) = 3
Дараах тохиолдолд зөрчилөөс зайлсхийх боломжтой:
Түлхүүрийн тоо > Хеш хүснэгтийн хэмжээ
Зөрчилөөс зайлсхийхийн тулд:
Хеш хүснэгтийн мөр бүрд түлхүүрүүдийг байрлуулахаар сонгож чаддаг хеш функцийг сонгох.
2 түлхүүрт Хэшийн ижил орон зайг тодорхойлсон утга гарсан тохиолдолд зөрчил үүснэ. Түүнийг шийдэх 2 арга байдаг:
- Hashing with Chaining:
Хэш хүснэгтийн үүр бүр нь ижил индекстэй түлхүүрүүд бүхий бичлэгүүдийн холбоост жагсаалтыг заасан заагчыг агуулдаг
- Hashing with Open Addressing:
Хэш хүснэгтийн үүр бүр нь зөвхөн ганц түлхүүрийг агуулдаг. Хэрэв шинэ түлхүүр нь мэдээлэл хадгалагдсан үүр рүү чиглүүлэгдвэл (индекс нь давхардвал) хоосон орон зайг олтол хүснэгтийн орон зайнуудыг шалгадаг.
Нээлттэй үүртэй хеш хүснэгт
Bucket – Хеш хүснэгтийн үүр буюу орон зай
Open-bucket hash table: Хадгалах орон зай нь Ганц өгөгдлийн элементэд л зориулагдсан байдаг
Түлхүүрийг хувиргасны дүнд home bucket буюу хадгалах үүр гардаг
Хаалттай үүртэй хэш хүснэгт
Closed-bucket hash table: Үүр буюу хадгалах орон зай нь өгөгдлийн элементүүдийн цуглуулгад зориулагдсан байдаг
Hash функцын жишээ
int hash(char * key)
{
int val = 0;
while(*key != '\0')
{
val = (val << 4) + (*key);
key++;
}
return val;
}
int compress(int index, int size)
{
return abs(index % size);
}