Hash Table concept แบบละเอียดสำหรับผู้เริ่มต้น
บทนี้จะพาเริ่มจากภาพรวมของตารางแฮช (Hash Table) ก่อน แล้วค่อยลงลึก เรื่อง key-value, hash function, index, bucket, ขั้นตอน insert/search/delete และการใช้งานจริงที่เจอบ่อยในงานเขียนโปรแกรม
1. Hash Table คืออะไร
ตารางแฮช (Hash Table) คือโครงสร้างข้อมูลที่เก็บข้อมูลเป็นคู่แบบคีย์-ค่า (key-value) โดยใช้สูตรคำนวณที่เรียกว่าแฮชฟังก์ชัน (hash function) เพื่อหา index สำหรับเก็บหรือค้นหาข้อมูลอย่างรวดเร็ว
จุดเด่นคือการเข้าถึงข้อมูลด้วย key มักทำได้เร็วมากในค่าเฉลี่ย
2. ทำไมเราต้องมี Hash Table
ถ้าเราเก็บข้อมูลผู้ใช้เป็นลิสต์ธรรมดา เมื่ออยากหา user โดย email อาจต้องไล่เช็กทีละตัว (O(n)) แต่ถ้าใช้ตารางแฮช (Hash Table) เราสามารถกระโดดไปตำแหน่งที่น่าจะเก็บข้อมูลนั้นได้ทันทีในค่าเฉลี่ย (O(1))
จึงเหมาะกับระบบที่ต้องค้นหาซ้ำ ๆ เช่น session, cache, dictionary, ตรวจข้อมูลซ้ำ, นับความถี่คำ
3. เปรียบเทียบกับ array แบบง่าย ๆ
อาเรย์ (Array)
เด่นเรื่องเข้าถึงด้วยตำแหน่ง (index) เช่น arr[3] แต่ถ้าค้นหาจากค่า key โดยตรงมักต้องไล่หา
ตารางแฮช (Hash Table)
เด่นเรื่องเข้าถึงด้วย key เช่น email, username, productId โดยไม่ต้องไล่ทุกสมาชิกในค่าเฉลี่ย
4. อธิบายแนวคิด key-value
key คือรหัสอ้างอิงที่ไม่ซ้ำ (เช่น "alice") และ value คือข้อมูลจริง (เช่น เบอร์โทรของ alice) เราใช้ key เพื่อเข้าถึง value โดยตรง
ภาพจำง่าย: key เป็นป้ายลิ้นชัก และ value คือของที่เก็บในลิ้นชักนั้น
5. อธิบายว่าข้อมูลถูกนำไปเก็บในตำแหน่งต่าง ๆ ได้อย่างไร
เมื่อได้ key ระบบจะส่ง key เข้าแฮชฟังก์ชัน (hash function) เพื่อแปลงเป็นเลข จากนั้นใช้เลขนั้นคำนวณเป็น index แล้วนำข้อมูลไปเก็บที่ bucket ของ index นั้น
สรุปสั้น: key -> hash function -> index -> bucket
6. อธิบายคำสำคัญ
key
ค่าที่ใช้ระบุตัวตนข้อมูล เช่น username, email, id
value
ข้อมูลที่ต้องการเก็บจริง เช่น โปรไฟล์ผู้ใช้, คะแนน, จำนวนครั้ง
hash function
ฟังก์ชันที่รับ key แล้วคืนเลข เพื่อใช้หา index
index
ตำแหน่งในอาเรย์หลักที่ได้จากการคำนวณ hash(key) % size
bucket
ช่องเก็บข้อมูลใน index หนึ่ง ๆ อาจเก็บได้มากกว่า 1 คู่ key-value เมื่อเกิดการชนกัน (collision)
7. ตัวอย่างง่าย ๆ เช่น เก็บชื่อคนกับเบอร์โทร
สมมติเราทำสมุดโทรศัพท์ โดยใช้ชื่อเป็น key และเบอร์โทรเป็น value
ตัวอย่างระดับเริ่มต้นให้เห็นภาพก่อนเข้า operation
8. อธิบายขั้นตอนการ insert ข้อมูล
- รับ key และ value ที่ต้องการเก็บ
- คำนวณ hash จาก key
- แปลง hash เป็น index
- ไปที่ bucket ตาม index
- ถ้า key ซ้ำ ให้ update value เดิม
- ถ้ายังไม่มี key นี้ ให้เพิ่มคู่ใหม่ลง bucket
9. อธิบายขั้นตอนการ search ข้อมูล
- รับ key ที่ต้องการค้นหา
- คำนวณ hash และ index เหมือนตอน insert
- เปิด bucket ที่ index นั้น
- ตรวจคู่ key-value ใน bucket ว่ามี key ตรงกันหรือไม่
- ถ้าเจอคืน value ถ้าไม่เจอคืน undefined หรือ not found
10. อธิบายขั้นตอนการ delete ข้อมูลแบบภาพรวม
- รับ key ที่ต้องการลบ
- คำนวณ index จาก hash(key)
- ไปที่ bucket นั้นแล้วค้นหาคู่ที่ key ตรงกัน
- ลบคู่นั้นออกจาก bucket
- คืนสถานะว่า delete สำเร็จหรือไม่สำเร็จ
11. Pseudocode ของ insert / search / delete
โครงหลักที่ใช้ใน Hash Table แบบ chaining
12. ตัวอย่างโค้ด JavaScript แบบง่าย
ตัวอย่างพื้นฐานที่มี insert, search, delete ครบ
13. Average Time Complexity ของ insert / search / delete
insert
Average: O(1)
Worst: O(n)
เฉลี่ยเร็วเพราะกระจาย bucket แต่แย่สุดอาจชน bucket เดียวกันมาก
search
Average: O(1)
Worst: O(n)
เฉลี่ยเข้าถึง bucket ได้เร็ว แต่แย่สุดต้องไล่ทั้งโครงสร้าง
delete
Average: O(1)
Worst: O(n)
หลักการเหมือน search: ต้องหา key ก่อนจึงลบได้
14. Worst case คืออะไร และเกิดขึ้นได้อย่างไร
กรณีแย่ที่สุด (Worst case) ของ Hash Table มักเป็น O(n) เพราะ key หลายตัวถูกแฮชไปที่ bucket เดียวกัน (collision หนาแน่น) จนต้องไล่เช็กข้อมูลจำนวนมากใน bucket เดียว
สาเหตุที่พบบ่อยคือ hash function ไม่กระจายดี, ขนาดตารางเล็กเกินไป, หรือ load factor สูงเกินไป
15. ข้อดีของ Hash Table
- ค้นหา เพิ่ม ลบ เร็วมากในค่าเฉลี่ย (O(1))
- เหมาะกับงาน key-value ที่ต้องเรียกบ่อย
- โค้ดอ่านง่ายและนำไปใช้กับโจทย์จริงได้กว้าง
- รองรับเคสเช็กข้อมูลซ้ำและนับความถี่ได้ดี
16. ข้อจำกัดของ Hash Table
- กรณี collision เยอะ ประสิทธิภาพตกลงได้มาก
- ไม่เหมาะกับงานที่ต้องเรียงข้อมูลโดยธรรมชาติ
- ต้องออกแบบ hash function และขนาดตารางให้เหมาะ
- มีต้นทุนหน่วยความจำเพิ่มสำหรับ bucket และการขยายตาราง
17. ตัวอย่างการใช้งานจริงในโปรแกรม
เก็บข้อมูลผู้ใช้
ใช้ userId หรือ email เป็น key แล้วเก็บโปรไฟล์เป็น value
ค้นหาคำในข้อความ
ใช้คำเป็น key และจำนวนครั้งที่เจอเป็น value สำหรับ word frequency
ตรวจข้อมูลซ้ำ
เก็บค่าที่เคยเจอใน set (set เป็นโครงสร้างบน hashing) เพื่อตรวจ duplicate ได้เร็ว
แคชข้อมูล
เก็บผลคำนวณหรือผลเรียก API โดยใช้ key จากพารามิเตอร์คำขอ
18. เปรียบเทียบสั้น ๆ กับ Array และ Object/Map
| โครงสร้าง | จุดเด่น | เหมาะกับงาน |
|---|---|---|
| Array | เข้าถึงตาม index เร็ว | ข้อมูลมีลำดับชัดเจน |
| Object / Map | เข้าถึงด้วย key สะดวก | พจนานุกรมข้อมูล (dictionary) |
| Hash Table | ค้นหา/เพิ่ม/ลบ เร็วในค่าเฉลี่ย | งาน lookup หนัก ๆ และเช็กซ้ำ |
19. สรุปท้ายบทแบบจำง่าย
จำประโยคเดียว: Hash Table คือ key-value store ที่ใช้ hash function พาเราไป index ของ bucket อย่างรวดเร็ว
สูตรจำสั้น: key -> hash function -> index -> bucket -> value
20. แบบฝึกหัด 3 ข้อ พร้อมแนวเฉลย (use playground)
ข้อ 1: เขียนฟังก์ชันนับความถี่ตัวอักษร
รับสตริง (string) แล้วคืนค่า object ที่บอกจำนวนครั้งของแต่ละตัวอักษร
แนวเฉลยย่อ: วนลูปทีละตัวอักษร ใช้อักษรเป็น key และเพิ่มตัวนับ value ทีละ 1
ข้อ 2: ตรวจว่ามีข้อมูลซ้ำในอาเรย์หรือไม่
คืนค่า true ถ้ามีสมาชิกซ้ำ และ false ถ้าไม่ซ้ำ
แนวเฉลยย่อ: เก็บค่าที่เคยเห็นไว้ใน set หรือ hash map ถ้าเจอซ้ำให้คืน true ทันที
ข้อ 3: สร้าง phoneBook แบบง่าย
รองรับคำสั่ง insert(name, phone), search(name), delete(name)
แนวเฉลยย่อ: ใช้โครง key-value และคืน undefined เมื่อหาไม่เจอ
ภาพประกอบแนวคิดสำคัญ
ภาพที่ 1: key ถูกส่งเข้า hash function แล้วได้ index
- เริ่มจาก key เช่น alice
- ส่ง key เข้า hash function
- ได้ค่าตัวเลขแล้วคำนวณเป็น index
- index นี้จะชี้ไป bucket ปลายทาง
key -> hash function -> index -> bucket
ภาพที่ 2: array หรือ bucket ที่มีช่องเก็บข้อมูล
- ตารางหลักคืออาเรย์ของ bucket
- แต่ละช่องมี index ของตัวเอง
- ค่าที่ hash ได้จะพาไป index ช่องหนึ่ง
- ข้อมูล key-value จะถูกเก็บใน bucket ช่องนั้น
key -> hash function -> index -> bucket
ภาพที่ 3: key-value ถูกเก็บในตำแหน่งที่คำนวณได้
- รับ key และ value ที่ต้องการเก็บ
- คำนวณ hash ของ key เพื่อหา index
- ไปยัง bucket ของ index นั้น
- บันทึกคู่ key-value ลง bucket
key -> hash function -> index -> bucket