4
Page 1 of 4 პრაქტიკული მეცადინება 8 სააუდიტორიო სამუშაო: ზოგადი ცნობები ორმაგი ჰეშირების შესახებ და ელემენტის ჩამატების ფსევდოკოდი ამოცანა 1 /ჰეშ-ცხრილში ელემენტების ჩასმა/ >>> ამოცანა 2 /ჰეშირება ჯაჭვებით/ >>> სავარჯიშოები >>> ზოგადი ცნობები ორმაგი ჰეშირების შესახებ და ჩამატების ფსევდოკოდი ჩვენი ამოცანაა გასაღებები (უნიკალური ნატურალური რიცხვები) შევინახოთ ერთგანზომილებიან ცხრილში გასაღებების სიდიდის გათვალისწინებით. ცხრილის გადანომვრა იწყება ნულიდან. ცხრილი აღვნიშნოთ T-თი, ხოლო მისი მოცულობა (უჯრების რაოდენობა) m-ით. ვიგულისხმოთ, რომ აქტიური გასაღებების რაოდენობა ყოველ მომენტში უფრო მცირეა, ვიდრე ცხრილის ზომა, ანუ ყოველთვის არის ღია მისამართები. ღია მისამართების განსაზღვრისთვის ახლა გამოვიყენოთ ორმაგი ჰეშირება, როდესაც k გასაღების შენახვას i-ურ ცდაზე ვცდილობთ , Hki = 1 2 % h k ih k m მისამართზე, სადაც 1 2 , h k h k ორი ჰეშ-ფუნქციაა, რომელთაგან მეორე აუცილებლად ნულისგან განსხვავებულ მნიშვნელობებს უნდა იძლეოდეს. ჰეშ-ფუნქცია გაყოფით ითვლის მისამართებს, როდესაც % hk k m , ხოლო გამრავლებით ითვლის, როდესაც () mod 1 hk m kA . ხშირად იღებენ 5 1 /2 0.6180339887. A როდესაც ორმაგ ჰეშირებაში მეორე ჰეშ- ფუნქცია გაყოფით ითვლის მისამართებს, მაშინ იგი უნდა ავიღოთ ასეთი სახით: 1 % 1 hk k m , ამ დროს ჰეშ-მნიშვნელობები არის 1, 2, , 1 m დიაპაზონში. ანალოგიურად, იგივე დიაპაზონში რომ მიიღოს მნიშვნელობები ჰეშ-ფუნქციამ, რომელიც გამრავლებას იყენებს, უნდა გამოვიყენოთ ფორმულა: () 1 1 mod 1 hk m kA . ელემენტის ჩამატების ალგორითმი, ცხადია, იგივეა რაც წინა მეცადინეობაზე: int insert(int k) { for(int i=0; i<m; i++) { int j = H(k,i); if( T[j]<=0) { T[j] = k; size++; return j; } } cout << "Hash Table Overflow!" << endl; return m;

P8 2014 ორმაგი ჰეშირება. ჰეშირება ჯაჭვებით

Embed Size (px)

Citation preview

Page 1: P8 2014 ორმაგი ჰეშირება. ჰეშირება ჯაჭვებით

Page 1 of 4

პრაქტიკული მეცადინება 8

სააუდიტორიო სამუშაო: ზოგადი ცნობები ორმაგი ჰეშირების შესახებ და ელემენტის ჩამატების ფსევდოკოდი

ამოცანა 1 /ჰეშ-ცხრილში ელემენტების ჩასმა/ >>> ამოცანა 2 /ჰეშირება ჯაჭვებით/ >>>

სავარჯიშოები >>>

ზოგადი ცნობები ორმაგი ჰეშირების შესახებ და ჩამატების ფსევდოკოდი ჩვენი ამოცანაა გასაღებები (უნიკალური ნატურალური რიცხვები) შევინახოთ

ერთგანზომილებიან ცხრილში გასაღებების სიდიდის გათვალისწინებით. ცხრილის

გადანომვრა იწყება ნულიდან. ცხრილი აღვნიშნოთ T-თი, ხოლო მისი მოცულობა (უჯრების

რაოდენობა) m-ით.

ვიგულისხმოთ, რომ აქტიური გასაღებების რაოდენობა ყოველ მომენტში უფრო მცირეა, ვიდრე

ცხრილის ზომა, ანუ ყოველთვის არის ღია მისამართები.

ღია მისამართების განსაზღვრისთვის ახლა გამოვიყენოთ ორმაგი ჰეშირება, როდესაც k

გასაღების შენახვას i-ურ ცდაზე ვცდილობთ

,H k i = 1 2 %h k ih k m

მისამართზე, სადაც 1 2,h k h k ორი ჰეშ-ფუნქციაა, რომელთაგან მეორე აუცილებლად

ნულისგან განსხვავებულ მნიშვნელობებს უნდა იძლეოდეს.

ჰეშ-ფუნქცია გაყოფით ითვლის მისამართებს, როდესაც

%h k k m ,

ხოლო გამრავლებით ითვლის, როდესაც

( ) mod1h k m kA .

ხშირად იღებენ 5 1 / 2 0.6180339887.A როდესაც ორმაგ ჰეშირებაში მეორე ჰეშ-

ფუნქცია გაყოფით ითვლის მისამართებს, მაშინ იგი უნდა ავიღოთ ასეთი სახით:

1 % 1h k k m ,

ამ დროს ჰეშ-მნიშვნელობები არის 1,2, , 1m დიაპაზონში. ანალოგიურად, იგივე

დიაპაზონში რომ მიიღოს მნიშვნელობები ჰეშ-ფუნქციამ, რომელიც გამრავლებას იყენებს, უნდა

გამოვიყენოთ ფორმულა:

( ) 1 1 mod1h k m kA .

ელემენტის ჩამატების ალგორითმი, ცხადია, იგივეა რაც წინა მეცადინეობაზე:

int insert(int k) { for(int i=0; i<m; i++) { int j = H(k,i); if( T[j]<=0) { T[j] = k; size++; return j; } } cout << "Hash Table Overflow!" << endl; return m;

Page 2: P8 2014 ორმაგი ჰეშირება. ჰეშირება ჯაჭვებით

Page 2 of 4

}

<<< ამოცანა 1: თავდაპირველად ცარიელ 11-ელემენტიან ჰეშ ცხრილში, ორმაგი ჰეშირებით

განსაზღვრეთ ღია მისამართები და ჩაამატეთ გასაღებები 10, 22, 31, 4, 15, 28, 17, 88, 59. პირველი

ჰეშ-ფუნქცია ავიღოთ გამრავლების მეთოდით, მეორე ჰეშ ფუნქცია კი გაყოფის მეთოდით.

ამოხსნა: ვნახოთ ჰეშ-ფუნქციების მნიშვნელობები ამ გასაღებებზე m=11 -სთვის.

k 5 1

11 mod12

k

1+k%10

10 1 1

22 6 3

31 1 2

4 5 5

15 2 6

28 3 9

17 5 8

88 4 9

59 5 10

ვისარგებლოთ ფორმულით:

,H k i = 1 2 %h k ih k m

ჩავამატოთ k=10:

0i , 1 210,0 ( 10 0 10 )%11 1j H h h , ეს მისამართი ღიაა და გასაღები ჩაჯდება:

0 1 2 3 4 5 6 7 8 9 10

0 10 0 0 0 0 0 0 0 0 0

ჩავამატოთ k=22:

0i , 1 2 122,0 ( 22 0 22 )%11 22 6j H h h h , მისამართი ღიაა.

0 1 2 3 4 5 6 7 8 9 10

0 10 0 0 0 0 22 0 0 0 0

ჩავამატოთ k=31:

0i 1 2 131,0 ( 31 0 31 )%11 31 1j H h h h , ეს მისამართი დაკავებულია,

1i , 1 115,1 ( 31 31 )%11 1 2 %11 3j H h h , ეს მისამართი ღიაა:

0 1 2 3 4 5 6 7 8 9 10

0 10 0 31 0 0 22 0 0 0 0

ჩავამატოთ k=4:

0i , 1 24,0 ( 4 0 4 )%11 5j H h h , ეს მისამართი ღიაა და გასაღები ჩაჯდება:

0 1 2 3 4 5 6 7 8 9 10

0 10 0 31 0 4 22 0 0 0 0

ჩავამატოთ k=15:

0i , 1 215,0 ( 15 0 15 )%11 2j H h h , ეს მისამართი ღიაა:

Page 3: P8 2014 ორმაგი ჰეშირება. ჰეშირება ჯაჭვებით

Page 3 of 4

0 1 2 3 4 5 6 7 8 9 10

0 10 15 31 0 4 22 0 0 0 0

ჩავამატოთ k=28:

0i , 1 228,0 ( 28 0 28 )%11 3j H h h , ეს მისამართი დაკავებულია;

1i , 1 228,1 ( 28 1 28 )%11 (3 9)%11 1j H h h , ეს მისამართიც დაკავებულია;

2i , 1 228,2 ( 28 2 28 )%11 (3 18)%11 10j H h h , ეს მისამართი ღიაა;

0 1 2 3 4 5 6 7 8 9 10

0 10 15 31 0 4 22 0 0 0 28

ჩავამატოთ k=17:

0i , 1 217,0 ( 17 0 17 )%11 5j H h h , ეს მისამართი დაკავებულია;

1i , 1 217,1 ( 17 1 17 )%11 (5 8)%11 2j H h h , ეს მისამართიც დაკავებულია;

2i , 1 217,2 ( 17 2 17 )%11 (5 16)%11 10j H h h , ეს მისამართიც დაკავებულია;

3i , 1 217,3 ( 17 3 17 )%11 (5 24)%11 7j H h h . ეს მისამართი ღიაა;

0 1 2 3 4 5 6 7 8 9 10

0 10 15 31 0 4 22 17 0 0 28

ჩავამატოთ k=88:

0i , 1 288,0 ( 88 0 88 )%11 4j H h h , ეს მისამართი ღიაა:

0 1 2 3 4 5 6 7 8 9 10

0 10 15 31 88 4 22 17 0 0 28

ჩავამატოთ k=59:

0i , 1 259,0 ( 59 0 59 )%11 5j H h h , ეს მისამართი დაკავებულია;

1i , 1 259,1 ( 59 59 )%11 (5 10)%11 4j H h h ,

2i , 1 259,2 ( 59 2 59 )%11 (5 20)%11 3j H h h ,

1 23, 59,3 ( 59 3 59 )%11 (5 30)%11 2i j H h h ,

1 24, 59,4 ( 59 4 59 )%11 (5 40)%11 1i j H h h ,

და ბოლოს. როცა 5, 59,5 0i j H არის ღია მისამართი:

0 1 2 3 4 5 6 7 8 9 10

59 10 15 31 88 4 22 17 0 0 28

<<< ამოცანა 2 /ჰეშირება ჯაჭვებით/: გრაფიკულად წარმოვიდგინოთ ჰეშ-ცხრილის შექმნა

ჯაჭვებით (სიებით, გადაბმით) ჰეშირებით, თუ ცხრილის მოცულობაა m=3 და ჰეშ ფუნქციას

ვიღებთ გაყოფის მეთოდით;

ჰეშ-ცხრილი 1,2,3,4,5 გასაღებების ჩასმის შემდეგ;

ჰეშ-ცხრილი 4-ის წაშლის და 100,22,33 გასაღებების ჩასმის შემდეგ:

ამოხსნა. ჰეშ-ცხრილის ობიექტის შექმნისას, ცხრილის უჯრებში ჩაიწერება ცარიელი სიების

მისამართები:

Page 4: P8 2014 ორმაგი ჰეშირება. ჰეშირება ჯაჭვებით

Page 4 of 4

ჰეშ-ცხრილი 1,2,3,4,5 გასაღებების ჩასმის შემდეგ:

ჰეშ-ცხრილი 4-ის წაშლის და 100,22,33 გასაღებების ჩასმის შემდეგ:

<<< სავარჯიშო

1. ამოხსენით ამოცანა 1, ოღონდ ჰეშ-ფუნქციები გადაანაცვლეთ.

(მითითება: მივყვებით ძებნის და წაშლის ალგორითმის ფსევდოკოდების სტრიქონებს : int search(int k) { int i = 0; while( true) { int j = H(k,i); if( T[j] == k) return j; ifT[j] == 0 || i == m) return m; i++; } } void erase(int k) { int j = search(k); if( j != m ) { T[j] = -1; size--; } }

2. ამოცანაა 1-ის ჰეშ-ცხრილში წავშალოთ ელემენტი 15, მერე წავშალოთ 59.

3. თავდაპირველად ცარიელ 13-ელემენტიან ჰეშ ცხრილში ჩაამატეთ გასაღებები 10, 22, 31,

4, 15, 28, 17, 88, 59 77 და 40, ღია მისამართები განსაზღვრეთ ორმაგი ჰეშირებით.

4. წინა სავარჯიშოში აგებულ ცხრილში, წაშალეთ ელემენტი 15, შემდეგ 59.

5. განვახორციელოთ ჰეშირება ჯაჭვებით, ცხრილის მოცულობაა m=3, ჰეშ ფუნქცია ავიღოთ

გამრავლების მეთოდით. ჩავსვათ ცხრილში ელემენტები: 10, 22, 31, 4, 15, 28, 17, 88, 59 77

და 40, შემდეგ წავშალოთ 15 და 59.

ჰეშ ცხრილი T [3]

ცარიელი სია

ცარიელი სია

ცარიელი სია

ჰეშ ცხრილი T [3]

3 N

4 1 N

5 2 N

ჰეშ ცხრილი T [3]

33 3 N

22 100 1 N

5 2 N