การจัดการข้อมูลในโปรแกรมมิ่งเป็นส่วนสำคัญที่จะช่วยให้โปรแกรมนั้นสามารถทำงานได้อย่างมีประสิทธิภาพ หนึ่งในเทคนิคการจัดการข้อมูลที่สามารถจัดการกับคอลิชัน (collision) ได้เป็นอย่างดีคือการใช้ระบบ Hashing โดยเฉพาะ Separate Chaining Hashing ซึ่งเป็นวิธีหนึ่งในการจัดการชนิดของการกระจายของข้อมูลเมื่อเกิดการชนกัน (collision) ในตารางแฮช (hash table) วันนี้เราจะมาดูเทคนิคการใช้ Separate Chaining Hashing ในภาษาโปรแกรมมิ่ง Golang กันครับ
Seperate Chaining เป็นเทคนิคการจัดการการชนของข้อมูลใน hash table โดยการใช้โครงสร้างข้อมูลเชิงเชื่อมต่อ เช่น linked lists หรือ binary trees เพื่อเก็บรายการที่มี hash value เดียวกัน ซึ่งช่วยให้แต่ละ slot ใน hash table สามารถจัดเก็บได้มากกว่าหนึ่งค่า
สำหรับ Golang เราสามารถสร้างโครงสร้างข้อมูลต่างๆ เช่น structs และเมธอดที่เกี่ยวข้องได้ง่าย เราจะมาเริ่มกันที่การสร้าง hash table และนิยาม linked list ที่จะใช้ภายในแต่ละ slot:
package main
import (
"fmt"
)
// Element คือโครงสร้างข้อมูลที่เก็บข้อมูลและอ้างถึง element ถัดไป
type Element struct {
Key string
Value string
Next *Element
}
// HashTable คือโครงสร้างของ hash table ที่มีขนาดเป็นพื้นฐาน
type HashTable struct {
Size int
Table map[int]*Element
}
// InitHashTable สร้าง hash table ใหม่
func InitHashTable(size int) *HashTable {
return &HashTable{
Size: size,
Table: make(map[int]*Element),
}
}
// HashFunction คือฟังก์ชั่นที่ใช้สำหรับการแปลงคีย์เป็น index ใน hash table
func (h *HashTable) HashFunction(key string) int {
hash := 0
for i := 0; i < len(key); i++ {
hash += int(key[i])
}
return hash % h.Size
}
// Insert เพิ่ม element ใหม่เข้าไปใน hash table
func (h *HashTable) Insert(key string, value string) {
index := h.HashFunction(key)
element := &Element{Key: key, Value: value, Next: h.Table[index]}
h.Table[index] = element
}
// Find ค้นหาค่าที่ตรงกับคีย์
func (h *HashTable) Find(key string) (*Element, bool) {
index := h.HashFunction(key)
element := h.Table[index]
for element != nil {
if element.Key == key {
return element, true
}
element = element.Next
}
return nil, false
}
// Delete ลบ element ที่ตรงกับคีย์
func (h *HashTable) Delete(key string) bool {
index := h.HashFunction(key)
element := h.Table[index]
var prev *Element
for element != nil {
if element.Key == key {
if prev == nil {
h.Table[index] = element.Next
} else {
prev.Next = element.Next
}
return true
}
prev = element
element = element.Next
}
return false
}
// ฟังก์ชั่นหลักเพื่อแสดงการทำงานของโครงสร้างข้อมูล
func main() {
hashTable := InitHashTable(5)
hashTable.Insert("name", "Alice")
hashTable.Insert("role", "Admin")
hashTable.Insert("email", "alice@example.com")
element, found := hashTable.Find("email")
if found {
fmt.Printf("Found element: %+v\n", *element)
}
hashTable.Delete("name")
element, found = hashTable.Find("name")
if !found {
fmt.Println("Name key has been deleted")
}
}
โค้ดที่กล่าวมาข้างต้นนี้แสดงถึงการใช้ Seperate Chaining Hashing ใน Golang ที่ซึ่งเริ่มต้นที่การสร้าง hash table และรวมถึงการจัดการชนิดของการเก็บข้อมูล:
- `Insert` จะเพิ่มข้อมูลลงใน hash table โดยการสร้างองค์ประกอบใหม่และวางไว้ที่หน้าสุดของโซ่ต่อ (linked list) ที่อยู่ใน slot ของ hash table นั้นๆ
- `Find` จะทำการค้นหาข้อมูลใน hash table โดยการเรียกดูจาก index ที่ได้จาก hash function และจะค้นหาใน linked list จนกว่าจะพบค่าที่ต้องการหรือถึงสิ้นสุดของ list
- `Delete` จะลบข้อมูลลงใน hash table โดยการค้นหาองค์ประกอบที่ต้องการลบจาก linked list ใน slot นั้นไปจนพบและลบมันออกจากโซ่
ข้อดี:
1. ช่วยลดปัญหาของการชนของข้อมูลและช่วยให้สามารถจัดการข้อมูลได้หลากหลายเพิ่มขึ้น
2. สามารถเพิ่มข้อมูลลงในตารางแฮชได้มากขึ้นโดยไม่ต้องขยายขนาดตาราง
ข้อเสีย:
1. หากขนาดของข้อมูลในแต่ละ bucket (slot) มีขนาดใหญ่มาก การค้นหาสามารถช้าลงเนื่องจากต้องทำการวนผ่าน linked list
2. สิ้นเปลืองหน่วยความจำเพิ่มขึ้นเนื่องจากการจัดเก็บ pointer ในแต่ละโครงสร้าง linked list
การทำความเข้าใจการจัดการข้อมูลด้วยการใช้เทคนิคต่างๆ เช่น Seperate Chaining ใน Golang จะช่วยให้นักพัฒนาสามารถสร้างโปรแกรมที่มีประสิทธิภาพการจัดการข้อมูลที่ดีขึ้น หากคุณเป็นผู้ที่สนใจในการเรียนรู้การเขียนโค้ดเพื่อการจัดการข้อมูลหรือต้องการขยายความรู้ในการใช้ภาษา Golang อย่างลึกซึ้ง อย่าลืมลองเข้าร่วมคอร์สที่ EPT (Expert-Programming-Tutor) ของเรา เพื่อพัฒนาทักษะการเขียนโปรแกรมของคุณในทุกระดับความสามารถ เรามีหลากหลายโปรแกรมการเรียนรู้ที่จะให้คุณได้เรียนรู้และเติบโตอย่างมืออาชีพครับ!
หมายเหตุ: ข้อมูลในบทความนี้อาจจะผิด โปรดตรวจสอบความถูกต้องของบทความอีกครั้งหนึ่ง บทความนี้ไม่สามารถนำไปใช้อ้างอิงใด ๆ ได้ ทาง EPT ไม่ขอยืนยันความถูกต้อง และไม่ขอรับผิดชอบต่อความเสียหายใดที่เกิดจากบทความชุดนี้ทั้งทางทรัพย์สิน ร่างกาย หรือจิตใจของผู้อ่านและผู้เกี่ยวข้อง
หากมีข้อผิดพลาด/ต้องการพูดคุยเพิ่มเติมเกี่ยวกับบทความนี้ กรุณาแจ้งที่ http://m.me/Expert.Programming.Tutor
085-350-7540 (DTAC)
084-88-00-255 (AIS)
026-111-618
หรือทาง EMAIL: NTPRINTF@GMAIL.COM