ตารางแฮชเป็นโครงสร้างข้อมูลที่ใช้ในการจัดเก็บและเรียกข้อมูลอย่างรวดเร็ว ทำงานโดยใช้ฟังก์ชันแฮชเพื่อแมปคีย์ของรายการที่ถูกจัดเก็บไว้กับดัชนีเฉพาะในอาร์เรย์ ซึ่งทำให้สามารถเข้าถึงข้อมูลในเวลาคงที่ ไม่ว่าชุดข้อมูลจะมีขนาดเท่าใดก็ตาม .
ในตารางแฮช ข้อมูลจะถูกจัดเก็บไว้ใน คู่คีย์-ค่า เมื่อคุณต้องการเพิ่มหรือดึงข้อมูลรายการจากตาราง คุณจะต้องระบุคีย์และฟังก์ชันแฮชจะจับคู่คีย์กับดัชนีเฉพาะในอาร์เรย์ จากนั้นค่าจะถูกจัดเก็บไว้ที่ดัชนีนั้น หรือดึงข้อมูลจากดัชนีนั้น แล้วแต่กรณี
ตารางแฮชมีประสิทธิภาพมากในการจัดเก็บและเรียกข้อมูล และมีการใช้กันอย่างแพร่หลายในแอปพลิเคชันต่างๆ เช่น ฐานข้อมูล แคช และแฮชแมปในภาษาการเขียนโปรแกรม นำเสนอการค้นหา การแทรก และการลบที่รวดเร็ว ทำให้เป็นตัวเลือกยอดนิยมสำหรับการใช้งานอาร์เรย์ ชุด และแผนที่ที่เชื่อมโยง
การใช้งานนี้มีขนาดคงที่สำหรับตารางแฮช ซึ่งระบุไว้เมื่อสร้างอ็อบเจ็กต์ HashTable
มีเมธอด hash()
ที่ใช้คีย์เป็นอินพุตและส่งกลับดัชนีในอาร์เรย์ที่ควรจัดเก็บหรือดึงค่า วิธีการ insert()
, get()
และ remove()
ใช้วิธีการ hash()
เพื่อค้นหาดัชนี จากนั้นดำเนินการที่เกี่ยวข้องกับค่าที่เก็บไว้ที่ดัชนีนั้น
class HashTable { constructor(size) { this.size = size; this.buckets = new Array(size); } hash(key) { let hash = 0; for (let i = 0; i < key.length; i++) { hash += key.charCodeAt(i); } return hash % this.size; } insert(key, value) { let index = this.hash(key); if (!this.buckets[index]) { this.buckets[index] = []; } this.buckets[index].push({key, value}); } get(key) { let index = this.hash(key); if (!this.buckets[index]) return null; for (let i = 0; i < this.buckets[index].length; i++) { if (this.buckets[index][i].key === key) { return this.buckets[index][i].value; } } return null; } remove(key) { let index = this.hash(key); if (!this.buckets[index]) return null; for (let i = 0; i < this.buckets[index].length; i++) { if (this.buckets[index][i].key === key) { this.buckets[index].splice(i, 1); return; } } } } const hashTable = new HashTable(10); hashTable.insert('abc', 123); hashTable.insert('def', 456); console.log(hashTable.get('abc')); // 123 console.log(hashTable.get('def')); // 456 hashTable.remove('abc'); console.log(hashTable.get('abc')); // null
ฟังก์ชันแฮช
ฟังก์ชันแฮชคือฟังก์ชันที่รับอินพุต (เรียกว่า “คีย์”) และส่งกลับเอาต์พุตที่มีขนาดคงที่ (เรียกว่า “ค่าแฮช” หรือ “โค้ดแฮช”) ที่คำนวณตามคีย์ วัตถุประสงค์หลักของฟังก์ชันแฮชคือการนำอินพุตขนาดใหญ่และแมปเข้ากับเอาต์พุตที่เล็กกว่าในลักษณะที่ทำให้ง่ายต่อการค้นหาคีย์ต้นฉบับตามค่าแฮช แต่เป็นไปไม่ได้ที่จะสร้างคีย์ต้นฉบับตาม กับค่าแฮชเพียงอย่างเดียว
คุณสมบัติหลักของฟังก์ชันแฮชที่ดีคือ:
- มีประสิทธิภาพในการคำนวณ: ฟังก์ชันแฮชควรรวดเร็วในการคำนวณและไม่ต้องใช้ทรัพยากรจำนวนมาก
- การกำหนด: อินพุตเดียวกันควรสร้างเอาต์พุตเดียวกันเสมอ เพื่อให้สามารถค้นหาคีย์เดียวกันได้อย่างง่ายดายโดยใช้ค่าแฮชเดียวกัน
- การกระจายแบบสม่ำเสมอ: เอาต์พุตของฟังก์ชันแฮชควรมีการกระจายเท่าๆ กันในช่วงของค่าแฮชที่เป็นไปได้ เพื่อให้คีย์มีการกระจายเท่าๆ กันทั่วทั้งตารางแฮช
- ทนต่อการชนกัน: ฟังก์ชันแฮชควรลดความน่าจะเป็นที่คีย์สองคีย์ที่แตกต่างกันที่มีค่าแฮชเท่ากัน หรือที่เรียกว่าการชนกัน
ฟังก์ชันแฮชมีการใช้กันอย่างแพร่หลายในแอปพลิเคชันต่างๆ เช่น การจัดเก็บและการเรียกค้นข้อมูล การเข้ารหัส และการขุดข้อมูล ในบริบทของตารางแฮช ฟังก์ชันแฮชที่ดีควรจะสามารถแมปคีย์ของรายการที่ถูกจัดเก็บไว้กับดัชนีที่ไม่ซ้ำกันในอาร์เรย์ตารางแฮช เพื่อให้แต่ละคีย์สามารถแทรกและดึงข้อมูลได้อย่างง่ายดาย
มีฟังก์ชันแฮชที่แตกต่างกันมากมายที่สามารถใช้ได้ และตัวเลือกของฟังก์ชันแฮชนั้นขึ้นอยู่กับข้อกำหนดเฉพาะของแอปพลิเคชัน ฟังก์ชันแฮชทั่วไปบางฟังก์ชัน ได้แก่ แฮชแบบโมดูโล แฮชสากล และแฮชที่เข้ารหัส
ต่อไปนี้คือตัวอย่างอื่นๆ ของฟังก์ชันแฮชที่สามารถใช้ในตารางแฮช:
โมดูโล่แฮช
ฟังก์ชันแฮชนี้ใช้ตัวดำเนินการแบบโมดูโลเพื่อจับคู่คีย์กับดัชนีในอาร์เรย์ตารางแฮช ตัวอย่างเช่น:
function moduloHash(key, size) { let hash = 0; for (let i = 0; i < key.length; i++) { hash += key.charCodeAt(i); } return hash % size; }
แฮชการเข้ารหัส
นี่คือฟังก์ชันแฮชประเภทหนึ่งที่ใช้ฟังก์ชันแฮชที่สร้างแบบสุ่มสำหรับแต่ละคีย์ ซึ่งทำให้ทนทานต่อการโจมตีจากการชนกันมากขึ้น นี่คือตัวอย่างของฟังก์ชันแฮชสากล:
const crypto = require('crypto'); function cryptographicHash(key) { return crypto.createHash('sha1').update(key).digest('hex'); }
ตารางแฮชขนาดไดนามิก
ตารางแฮชสามารถนำไปใช้กับอาเรย์ปรับขนาดแบบไดนามิกได้ ซึ่งหมายความว่าขนาดของอาเรย์สามารถเปลี่ยนแปลงได้ตามจำนวนองค์ประกอบในตาราง
วิธีทั่วไปวิธีหนึ่งในการนำตารางแฮชขนาดไดนามิกไปใช้คือการใช้ปัจจัยโหลด ซึ่งเป็นการวัดว่าตารางแฮชเต็มแค่ไหน เมื่อจำนวนองค์ประกอบในตารางแฮชเกินเกณฑ์ที่กำหนด (กำหนดโดยปัจจัยโหลด) อาร์เรย์จะถูกปรับขนาดให้ใหญ่ขึ้นเพื่อให้มีที่ว่างสำหรับองค์ประกอบเพิ่มเติม ในทำนองเดียวกัน เมื่อจำนวนองค์ประกอบต่ำกว่าเกณฑ์ที่กำหนด อาเรย์จะถูกปรับขนาดให้เล็กลงเพื่อประหยัดพื้นที่
นี่คือตัวอย่างวิธีการใช้ตารางแฮชขนาดไดนามิกใน JavaScript โดยใช้ไวยากรณ์ ES6:
class HashTable { constructor() { this.size = 8; this.buckets = new Array(this.size); this.numElements = 0; } hash(key) { let hash = 0; for (let i = 0; i < key.length; i++) { hash += key.charCodeAt(i); } return hash % this.size; } insert(key, value) { this.numElements++; let index = this.hash(key); if (!this.buckets[index]) { this.buckets[index] = []; } this.buckets[index].push({ key, value }); if (this.numElements > this.size * 0.75) { this.resize(this.size * 2); } } get(key) { let index = this.hash(key); if (!this.buckets[index]) return null; for (let i = 0; i < this.buckets[index].length; i++) { if (this.buckets[index][i].key === key) { return this.buckets[index][i].value; } } return null; } remove(key) { this.numElements--; let index = this.hash(key); if (!this.buckets[index]) return null; for (let i = 0; i < this.buckets[index].length; i++) { if (this.buckets[index][i].key === key) { this.buckets[index].splice(i, 1); if (this.numElements < this.size * 0.25) { this.resize(this.size / 2); } return; } } } resize(newSize) { let oldBuckets = this.buckets; this.size = newSize; this.buckets = new Array(this.size); this.numElements = 0; for (let i = 0; i < oldBuckets.length; i++) { if (oldBuckets[i]) { for (let j = 0; j < oldBuckets[i].length; j++) { this.insert(oldBuckets[i][j].key, oldBuckets[i][j].value); } } } } }
การใช้งานในตัวตารางแฮช
JavaScript มีคลาสในตัวหลายคลาสที่ใช้ตารางแฮชเพื่อจัดเก็บและดึงข้อมูลอย่างมีประสิทธิภาพ ตัวอย่างบางส่วนได้แก่:
- แผนที่ - คลาส Map คือชุดของคู่คีย์-ค่าที่สามารถวนซ้ำตามลำดับที่เพิ่ม ใช้ตารางแฮชเพื่อจัดเก็บข้อมูลและให้การแทรก การลบ และเวลาในการค้นหา O(1) ที่มีประสิทธิภาพ
- ชุด - คลาส Set คือชุดของค่าที่ไม่ซ้ำกันซึ่งสามารถวนซ้ำตามลำดับที่เพิ่มเข้าไป นอกจากนี้ยังใช้ตารางแฮชเพื่อจัดเก็บข้อมูลและให้การแทรก การลบ และเวลาในการค้นหา O(1) ที่มีประสิทธิภาพ
คลาสในตัวเหล่านี้มอบวิธีที่สะดวกในการใช้ตารางแฮชใน JavaScript และมีประโยชน์มากสำหรับการจัดเก็บและจัดการข้อมูลอย่างมีประสิทธิภาพ
โดยรวมแล้ว ตารางแฮชเป็นโครงสร้างข้อมูลที่ ทรงพลัง และ มีประสิทธิภาพ ซึ่งสามารถปรับปรุงประสิทธิภาพของแอปพลิเคชันจำนวนมากได้อย่างมาก หากคุณกำลังทำงานในโปรเจ็กต์ที่ต้องการจัดเก็บและดึงข้อมูลอย่างมีประสิทธิภาพ ให้พิจารณาใช้ตารางแฮชเพื่อช่วยให้คุณบรรลุเป้าหมาย