User Tools

Site Tools


Sidebar

1. บทนำ

2. การวิเคราะห์ Algorithm

3. List, Stack and Queue

4. Tree

5. Hashing

6. Priority Queues

7. การจัดเรียง (Sorting)

8. The Disjoint Set

9. Graph Algorithms

dsa:hrehash

5.5 Rehashing

กล่าวสำหรับ Open addressing ที่ใช้ quadratic probe แล้ว เมื่อตารางถูกใช้งานจนใกล้จะเต็ม running time ของการดำเนินการต่าง ๆ ก็จะมากขึ้นและการบรรจุค่าใหม่ก็อาจจะทำไม่ได้เลย สิ่งนี้ยังเกิดขึ้นกับกรณีที่มีการลบและบรรจุร่วมกันจำนวนมาก ๆ ด้วย ทางแก้หนึ่งก็คือ สร้างตารางขึ้นใหม่ให้มีขนาดเป็นสองเท่า (ร่วมกับการใช้ hash function ใหม่) แล้วย้ายข้อมูลในตารางเดิมไปลงในตารางใหม่ด้วยการคำนวณค่า hash value ใหม่สำหรับแต่ละค่าที่อ่านจากตารางแฮชเดิม (ที่เป็น non-deleted)

ตัวอย่างเช่น ทำการบรรจุค่าสมาชิก 13, 15, 24, และ 6 ลงในตารางแฮชแบบ open addressing hash table ที่มีขนาด 7 เซลล์ และใช้ฟังก์ชันแฮช $h(x) = x\ mod\ 7$ และใช้ linear probing ผลการทำงานแสดงในรูปที่ 5.19

0 6
1 15
2
3 24
4
5
6 13
รูปที่ 5.19
0 6
1 15
2 23
3 24
4
5
6 13
รูปที่ 5.20

ถ้าต้องการบรรจุ 23 ลงในตารางผลที่ได้ก็จะเป็นดังรูปที่ 5.20 และตารางจะมีจำนวนข้อมูลมากกว่า 70 % ของขนาดตาราง ดังนั้นจึงสร้างตารางใหม่ขึ้นโดยให้มีขนาดเป็น 17 เซลล์ เนื่องจากตัวเลข 17 นี้เป็นค่า prime ตัวแรกที่มีค่ามากกว่า 2 เท่าของของขนาดตารางเดิม ฟังก์ชันแฮชตัวใหม่ที่ใช้ คือ $h(x) = x\ mod\ 17$ แล้วทำการอ่านค่าในตารางเดิมตามลำดับ คือ 6, 15, 23, 24, และ 13 เพื่อคำนวณและบรรจุลงในตารางใหม่ที่สร้างขึ้น ผลที่ได้ก็จะเป็นดังรูปที่ 5.21

0
1
2
3
4
5
6 6
7 23
8 24
9
10
11
12
13 13
14
15 15
16

รูปที่ 5.21 Open addressing หลังจากการ rehash

วิธีการดำเนินการที่กล่าวมานี้เรียกว่า rehashing จะเห็นได้ว่าวิธีนี้เป็นวิธีที่มีค่าใช้จ่ายสูงมาก กล่าวคือมี running time เป็น $O(N)$, เนื่องจากมีสมาชิกอยู่ N ตัวที่ต้อง rehash และขนาดของตารางโดยประมาณคือ $2N$ ซึ่งดูจะเป็น running time ที่ไม่ค่อยจะดีนัก, อย่างไรก็ตามการจะต้องทำการ rehash ตารางก็ไม่ใช่เป็นสิ่งที่จะต้องเกิดขึ้นบ่อย ๆ โดยเฉพาะอย่างยิ่งมันจะต้องมีการบรรจุค่าใหม่เกิดขึ้นก่อนถึง $N/2$ ค่า ก่อนที่จะต้องทำการ rehash

การทำ Rehashing ที่ใช้ quadratic probe สามารถทำได้หลายทางด้วยกัน วิธีการหนึ่งคือให้ทำการ rehash ทันทีที่เซลล์ตารางถูกใช้ไปถึงครึ่งหนึ่งของขนาดเต็มจำนวน หรืออีกทางเลือกคือ ให้ทำการ rehash เมื่อการบรรจุค่าใหม่เกิดความล้มเหลวขึ้น ทางเลือกที่ 3 เป็นทางเลือกกลาง ๆ กล่าวคือ ให้ทำการ rehash เมื่อตารางมีค่า load factor ที่ระดับที่กำหนดไว้ และเนื่องจากประสิทธิภาพจะลดลงไปเรื่อย ๆ เมื่อ load factor มีค่าเพิ่มขึ้น ดังนั้นการเลือกใช้วิธีที่ 3 ด้วยการกำหนดค่า load factor ที่เหมาะสม ฟังก์ชัน rehash เป็นฟังก์ชันที่ง่ายในการ implement รูปที่ 5.22 แสดงฟังก์ชัน rehash

private void rehash()
{
	HashEntry [] oldArray = array;
	allocateArray( nextPrime( 2 * oldArray.length ) );
	currentSize = 0;
	for ( int i = 0; i < oldArray.length; i++)
		if ( oldArray[i] != null && oldArray[i].isActive )
			insert ( oldArray[i].element );
}

รูปที่ 5.22 ฟังก์ชัน rehash

dsa/hrehash.txt · Last modified: 2021/09/09 08:36 by wasu

Page Tools