คำตอบของโจนั้นดีมากและให้คำสำคัญทั้งหมดแก่คุณ
คุณควรทราบว่าการวิจัยโครงสร้างข้อมูลที่กระชับยังอยู่ในช่วงเริ่มต้นและผลลัพธ์ส่วนใหญ่จะเป็นเชิงทฤษฎี โครงสร้างข้อมูลที่เสนอจำนวนมากมีความซับซ้อนในการใช้งาน แต่ความซับซ้อนส่วนใหญ่เกิดจากความจริงที่ว่าคุณต้องรักษาความซับซ้อนเชิงซีมโทติคทั้งขนาดจักรวาลและจำนวนองค์ประกอบที่เก็บไว้ ถ้าสิ่งใดสิ่งหนึ่งเหล่านี้ค่อนข้างคงที่ความซับซ้อนจำนวนมากก็หายไป
ถ้าคอลเลกชันกึ่งคงที่ (นั่นคือส่วนแทรกหายากหรืออย่างน้อยปริมาณต่ำ) ก็แน่นอนว่าคุ้มค่าที่จะพิจารณาโครงสร้างข้อมูลคงที่ง่ายต่อการใช้งาน (sdarray Sadakane เป็นตัวเลือกที่ดี) ร่วมกับการปรับปรุง ขุมทรัพย์ โดยทั่วไปคุณบันทึกการปรับปรุงในโครงสร้างข้อมูลแบบดั้งเดิม (เช่น B-tree, trie, ตารางแฮช) และอัปเดตโครงสร้างข้อมูล "หลัก" เป็นระยะ ๆ นี่เป็นเทคนิคที่ได้รับความนิยมอย่างมากในการดึงข้อมูลเนื่องจากดัชนีแบบกลับด้านมีข้อได้เปรียบมากมายสำหรับการค้นหา แต่ยากที่จะอัปเดตในสถานที่ หากเป็นกรณีนี้โปรดแจ้งให้เราทราบในความคิดเห็นและฉันจะแก้ไขคำตอบนี้เพื่อให้คำแนะนำแก่คุณ
หากเม็ดมีดบ่อยกว่านี้ฉันขอแนะนำการบีบแตรแบบย่อ แนวคิดพื้นฐานตรงไปตรงมามากพอที่จะอธิบายได้ที่นี่ดังนั้นฉันจะทำเช่นนั้น
ข้อมูลพื้นฐานทางทฤษฎีผลก็คือถ้าคุณเก็บ n องค์ประกอบจากจักรวาลของ ยู รายการและไม่มีข้อมูลอื่น ๆ (เช่นไม่มีความสัมพันธ์ระหว่างองค์ประกอบ) จากนั้นคุณต้องการ เข้าสู่ระบบ(ยูn) +O(1)บิตในการจัดเก็บ (ลอการิทึมทั้งหมดเป็นฐาน -2 เว้นแต่จะระบุไว้เป็นอย่างอื่น) คุณต้องการบิตจำนวนมาก ไม่มีทางรอบมัน
ตอนนี้บางคำศัพท์:
- หากคุณมีโครงสร้างข้อมูลที่สามารถจัดเก็บข้อมูลและสนับสนุนการทำงานของคุณได้ เข้าสู่ระบบ(ยูn) +O(1)บิตของพื้นที่เราเรียกสิ่งนี้ว่าโครงสร้างข้อมูลโดยนัย
- หากคุณมีโครงสร้างข้อมูลที่สามารถจัดเก็บข้อมูลและสนับสนุนการทำงานของคุณได้ เข้าสู่ระบบ(ยูn) +O(บันทึก(ยูn) )=(1+O(1))บันทึก(ยูn)บิตของพื้นที่เราเรียกสิ่งนี้ว่าโครงสร้างข้อมูลที่กะทัดรัด โปรดทราบว่าในทางปฏิบัติสิ่งนี้หมายความว่าค่าใช้จ่ายสัมพัทธ์ (สัมพันธ์กับค่าต่ำสุดทางทฤษฎี) อยู่ภายในค่าคงที่ มันอาจเป็น 5% ค่าใช้จ่ายหรือ 10% ค่าใช้จ่ายหรือ 10 เท่าของค่าใช้จ่าย
- หากคุณมีโครงสร้างข้อมูลที่สามารถจัดเก็บข้อมูลและสนับสนุนการทำงานของคุณได้ เข้าสู่ระบบ(ยูn) +o(เข้าสู่ระบบ(ยูn) )=(1+o(1))เข้าสู่ระบบ(ยูn)บิตของพื้นที่เราเรียกสิ่งนี้ว่าโครงสร้างข้อมูลที่รวบรัด
ความแตกต่างระหว่างรวบรัดและกะทัดรัดคือความแตกต่างระหว่างโอ๋น้อยและใหญ่โอ๋ ไม่สนใจสิ่งที่มีคุณค่าแน่นอนอยู่ครู่หนึ่ง ...
- ก.( n ) = O ( ฉ( n ) ) หมายความว่ามีค่าคงที่ ค และตัวเลข n0 เช่นนั้นสำหรับทุกคน n >n0, ก.( n ) < c ⋅ f( n ).
- ก.( n ) = o ( f( n ) ) หมายความว่าสำหรับค่าคงที่ทั้งหมด ค มีตัวเลขอยู่ n0 เช่นนั้นสำหรับทุกคน n >n0, ก.( n ) < c ⋅ f( n ).
อย่างไม่เป็นทางการทั้งใหญ่และเล็ก - ทั้งคู่ต่างอยู่ใน "ปัจจัยคงที่" แต่ด้วยขนาดใหญ่ - โอ้ค่าคงที่ถูกเลือกสำหรับคุณ (โดยนักออกแบบอัลกอริทึมผู้ผลิตซีพียูกฎแห่งฟิสิกส์หรืออะไรก็ตาม) แต่มีน้อย -OH คุณเลือกคงที่ด้วยตัวเองและมันสามารถมีขนาดเล็กเท่าที่คุณต้องการ อีกทางหนึ่งด้วยโครงสร้างข้อมูลที่ซับซ้อนค่าใช้จ่ายสัมพัทธ์จะลดลงตามขนาดของปัญหาที่เพิ่มขึ้น
แน่นอนขนาดของปัญหาอาจต้องเพิ่มขึ้นอย่างมากเพื่อให้ตระหนักถึงค่าใช้จ่ายที่เกี่ยวข้องที่คุณต้องการ แต่คุณไม่มีทุกสิ่ง
ตกลงด้วยสิ่งนั้นใต้เข็มขัดของเราเราจะใส่ตัวเลขลงไปในปัญหา สมมุติว่ากุญแจนั้นnจำนวนเต็มบิต (ดังนั้นขนาดจักรวาลคือ 2n) และเราต้องการเก็บ 2ม.ของจำนวนเต็มเหล่านี้ สมมติว่าเราสามารถจัดตารางแฮชในอุดมคติที่มีการเข้าพักเต็มรูปแบบและไม่มีการสูญเสียดังนั้นเราจึงต้องการ2ม. สล็อตแฮช
การดำเนินการค้นหาจะแฮช nคีย์บิตปิดบัง ม.บิตเพื่อค้นหาสล็อตแฮชจากนั้นตรวจสอบเพื่อดูว่าค่าในตารางตรงกับคีย์หรือไม่ จนถึงตอนนี้ดีมาก
ตารางแฮชนั้นใช้ n2ม.เกร็ด เราทำได้ดีกว่านี้ไหม
สมมติว่าฟังก์ชันแฮช ชั่วโมงกลับด้านได้ จากนั้นเราไม่จำเป็นต้องเก็บคีย์ทั้งหมดในแต่ละช่องแฮช ตำแหน่งของสล็อตแฮชให้คุณม. บิตของค่าแฮชดังนั้นหากคุณเก็บเฉพาะ n - mบิตที่เหลืออยู่คุณสามารถสร้างคีย์ใหม่จากข้อมูลทั้งสองชิ้นนั้น (ตำแหน่งสล็อตแฮชและค่าที่เก็บไว้ที่นั่น) ดังนั้นคุณจะต้อง( n - m )2ม. บิตของการจัดเก็บ
ถ้า 2ม. มีขนาดเล็กเมื่อเทียบกับ 2nการประมาณของสเตอร์ลิงและเลขคณิตเล็กน้อย (การพิสูจน์เป็นการออกกำลังกาย!) เผยให้เห็นว่า:
( n - m )2ม.= บันทึก(2n2ม.) +o(เข้าสู่ระบบ(2n2ม.) )
ดังนั้นโครงสร้างข้อมูลนี้สั้นกระชับ
อย่างไรก็ตามมีสองการจับ
การจับครั้งแรกคือการสร้างฟังก์ชั่นแฮช "ดี" กลับด้าน โชคดีที่มันง่ายกว่าที่คิด cryptographers ทำให้ฟังก์ชั่นกลับด้านได้ตลอดเวลามี แต่พวกมันเท่านั้นที่เรียกว่า "cyphers" ตัวอย่างเช่นคุณสามารถใช้ฟังก์ชันแฮชบนเครือข่าย Feistel ซึ่งเป็นวิธีที่ตรงไปตรงมาในการสร้างฟังก์ชั่นแฮชที่กลับด้านได้จากฟังก์ชั่นแฮชที่ไม่สามารถย้อนกลับได้
จับที่สองคือตารางแฮชจริงไม่เหมาะขอบคุณวันเกิดความขัดแย้ง ดังนั้นคุณจึงต้องการใช้ตารางแฮชที่มีความซับซ้อนมากขึ้นซึ่งจะทำให้คุณเข้าใกล้การเข้าพักเต็มโดยไม่มีการรั่วไหล Cuckoo hashing นั้นสมบูรณ์แบบสำหรับสิ่งนี้เพราะมันจะช่วยให้คุณเข้าใกล้ในอุดมคติในทางทฤษฎีและฝึกฝนอย่างใกล้ชิด
การแฮชของ Cuckoo นั้นต้องการฟังก์ชั่นแฮชที่หลากหลายและต้องการให้มีการติดแท็กค่าในช่องแฮชที่ใช้ฟังก์ชันแฮช ตัวอย่างเช่นถ้าคุณใช้ฟังก์ชันแฮชสี่ฟังก์ชันคุณต้องเก็บสองบิตเพิ่มเติมในแต่ละช่องแฮช นี้ยังคงรวบรัดเป็นม. เติบโตขึ้นดังนั้นจึงไม่เป็นปัญหาในทางปฏิบัติและยังคงเก็บคีย์ทั้งหมดไว้
โอ้คุณอาจต้องการดูต้นแวนเอมเดอโบสด้วย
ความคิดเพิ่มเติม
ถ้า n อยู่ที่ไหนซักแห่ง ยู2จากนั้น เข้าสู่ระบบ(ยูn) ประมาณ ยูดังนั้น (อีกครั้ง) สมมติว่าไม่มีความสัมพันธ์เพิ่มเติมระหว่างค่าโดยทั่วไปคุณไม่สามารถทำได้ดีกว่าบิตเวกเตอร์ คุณจะทราบว่าโซลูชันการแปลงแป้นพิมพ์ด้านบนจะทำให้ประสิทธิภาพลดลงในกรณีดังกล่าว (คุณจบการจัดเก็บหนึ่งบิตต่อหนึ่งช่องเสียบแฮช) แต่มันถูกกว่าเพียงใช้คีย์เป็นที่อยู่แทนที่จะใช้ฟังก์ชันแฮช
ถ้า n อยู่ใกล้กับ ยูวรรณคดีโครงสร้างข้อมูลที่กระชับทั้งหมดแนะนำให้คุณย้อนกลับไปใช้ความรู้สึกของพจนานุกรม เก็บค่าที่ไม่เกิดขึ้นในชุด อย่างไรก็ตามตอนนี้คุณต้องสนับสนุนการลบอย่างมีประสิทธิภาพและเพื่อรักษาพฤติกรรมที่กระชับคุณยังต้องสามารถลดขนาดโครงสร้างข้อมูลเมื่อองค์ประกอบเพิ่มเติมได้รับ "เพิ่ม" การขยายตารางแฮชเป็นการดำเนินการที่เข้าใจกันดี แต่การทำสัญญาไม่ใช่