กล่าวสำหรับ 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