ข้อดีของต้นไม้ค้นหาแบบไบนารีบนตารางแฮชคืออะไร?
ตารางแฮชสามารถค้นหาองค์ประกอบใดก็ได้ใน Theta (1) ครั้งและการเพิ่มองค์ประกอบนั้นง่ายพอ ๆ กัน .... แต่ฉันไม่แน่ใจว่าจะได้เปรียบในทางอื่น
ข้อดีของต้นไม้ค้นหาแบบไบนารีบนตารางแฮชคืออะไร?
ตารางแฮชสามารถค้นหาองค์ประกอบใดก็ได้ใน Theta (1) ครั้งและการเพิ่มองค์ประกอบนั้นง่ายพอ ๆ กัน .... แต่ฉันไม่แน่ใจว่าจะได้เปรียบในทางอื่น
คำตอบ:
โปรดจำไว้ว่า Binary Search Trees (อิงตามข้อมูลอ้างอิง) นั้นมีประสิทธิภาพในการจำ พวกเขาไม่สงวนหน่วยความจำไว้มากกว่าที่จำเป็น
ตัวอย่างเช่นหากฟังก์ชันแฮชมีช่วงR(h) = 0...100
คุณจะต้องจัดสรรอาร์เรย์ขององค์ประกอบ 100 (พอยน์เตอร์ถึง) แม้ว่าคุณจะแฮชเพียง 20 องค์ประกอบก็ตาม หากคุณต้องการใช้โครงสร้างการค้นหาแบบไบนารีเพื่อจัดเก็บข้อมูลเดียวกันคุณจะจัดสรรพื้นที่ได้มากเท่าที่คุณต้องการเท่านั้นรวมถึงข้อมูลเมตาบางส่วนเกี่ยวกับลิงก์
ข้อดีอย่างหนึ่งที่ไม่มีใครชี้ให้เห็นก็คือต้นไม้ค้นหาแบบไบนารีช่วยให้คุณทำการค้นหาช่วงได้อย่างมีประสิทธิภาพ
เพื่อแสดงให้เห็นถึงแนวคิดของฉันฉันต้องการสร้างกรณีที่รุนแรง สมมติว่าคุณต้องการรับองค์ประกอบทั้งหมดที่มีคีย์อยู่ระหว่าง 0 ถึง 5000 และจริงๆแล้วมีเพียงองค์ประกอบเดียวดังกล่าวและองค์ประกอบอื่น ๆ อีก 10,000 รายการที่คีย์ไม่อยู่ในช่วง BST สามารถทำการค้นหาช่วงได้อย่างมีประสิทธิภาพเนื่องจากไม่ได้ค้นหาแผนผังย่อยซึ่งเป็นไปไม่ได้ที่จะมีคำตอบ
แม้ว่าคุณจะค้นหาช่วงในตารางแฮชได้อย่างไร คุณจำเป็นต้องวนซ้ำทุกพื้นที่เก็บข้อมูลซึ่งก็คือ O (n) หรือคุณต้องมองหาว่ามี 1,2,3,4 ... มากถึง 5,000 ชิ้นหรือไม่ (แล้วคีย์ระหว่าง 0 ถึง 5,000 เป็นเซตที่ไม่มีที่สิ้นสุดล่ะเช่นคีย์สามารถเป็นทศนิยมได้)
"ข้อดี" อย่างหนึ่งของต้นไม้ไบนารีคือมันอาจถูกส่งผ่านเพื่อแสดงรายการองค์ประกอบทั้งหมดตามลำดับ นี่ไม่ใช่สิ่งที่เป็นไปไม่ได้กับตารางแฮช แต่ไม่ใช่การดำเนินการปกติอย่างใดอย่างหนึ่งการออกแบบโครงสร้างแฮช
นอกเหนือจากความคิดเห็นดีๆอื่น ๆ :
ตารางแฮชโดยทั่วไปมีลักษณะการทำงานของแคชที่ดีขึ้นโดยต้องอ่านหน่วยความจำน้อยลงเมื่อเทียบกับไบนารีทรี สำหรับตารางแฮชโดยปกติคุณจะได้รับการอ่านเพียงครั้งเดียวก่อนที่คุณจะสามารถเข้าถึงข้อมูลอ้างอิงที่เก็บข้อมูลของคุณได้ ต้นไม้ไบนารีถ้าเป็นตัวแปรที่สมดุลต้องมีบางอย่างตามลำดับของหน่วยความจำk * lg (n)อ่านค่าคงที่ k
ในทางกลับกันหากศัตรูรู้ฟังก์ชันแฮชของคุณศัตรูสามารถบังคับใช้ตารางแฮชของคุณเพื่อทำการชนกันซึ่งจะขัดขวางประสิทธิภาพของมันอย่างมาก วิธีแก้ปัญหาคือเลือกฟังก์ชันแฮชแบบสุ่มจากครอบครัว แต่ BST ไม่มีข้อเสียนี้ นอกจากนี้เมื่อความดันตารางแฮชเพิ่มขึ้นมากเกินไปคุณมักจะขยายขนาดและจัดสรรตารางแฮชใหม่ซึ่งอาจเป็นการดำเนินการที่มีราคาแพง BST มีพฤติกรรมที่ง่ายกว่าที่นี่และไม่มีแนวโน้มที่จะจัดสรรข้อมูลจำนวนมากในทันทีและทำการดำเนินการ rehashing
ต้นไม้มักจะเป็นโครงสร้างข้อมูลเฉลี่ยขั้นสูงสุด พวกเขาสามารถทำหน้าที่เป็นรายการได้อย่างง่ายดายสามารถแยกสำหรับการทำงานแบบขนานมีการกำจัดอย่างรวดเร็วแทรกและการค้นหาในการสั่งซื้อของO (LG n) พวกเขาทำอะไรไม่ดีเป็นพิเศษแต่ก็ไม่มีพฤติกรรมที่แย่เกินไปเช่นกัน
สุดท้าย BST นั้นง่ายกว่ามากในการนำไปใช้ในภาษาที่ใช้งานได้ (บริสุทธิ์) เมื่อเทียบกับตารางแฮชและพวกเขาไม่ต้องการการอัปเดตที่ทำลายล้างเพื่อดำเนินการ ( อาร์กิวเมนต์การคงอยู่โดย Pascal ด้านบน)
BSTs are much easier to implement in (pure) functional languages compared to hash-tables
- จริงเหรอ? ฉันต้องการเรียนรู้ภาษาที่ใช้งานได้ตอนนี้!
ข้อดีหลักของต้นไม้ไบนารีบนตารางแฮชคือต้นไม้ไบนารีให้การดำเนินการเพิ่มเติมสองอย่างที่คุณไม่สามารถทำได้ (อย่างง่ายดายและรวดเร็ว) ด้วยตารางแฮช
ค้นหาองค์ประกอบที่ใกล้เคียงที่สุด (ไม่จำเป็นต้องเท่ากับ) ค่าคีย์ตามอำเภอใจ (หรือใกล้เคียงที่สุดด้านบน / ล่าง)
วนซ้ำเนื้อหาของต้นไม้ตามลำดับการจัดเรียง
ทั้งสองเชื่อมต่อกัน - ต้นไม้ไบนารีจะเก็บเนื้อหาไว้ในลำดับที่เรียงลำดับดังนั้นสิ่งที่ต้องใช้ลำดับการเรียงนั้นจึงทำได้ง่าย
โครงสร้างการค้นหาแบบไบนารี (แบบสมดุล) ยังมีข้อได้เปรียบที่ความซับซ้อนของ asymptotic นั้นเป็นขอบเขตบนในขณะที่เวลา "คงที่" สำหรับตารางแฮชจะถูกตัดจำหน่าย: หากคุณมีฟังก์ชันแฮชที่ไม่เหมาะสมคุณอาจทำให้เวลาเชิงเส้นลดลงได้ แทนที่จะคงที่
แฮชแท็กจะใช้พื้นที่มากขึ้นเมื่อสร้างครั้งแรก - จะมีช่องว่างสำหรับองค์ประกอบที่ยังไม่ได้แทรก (ไม่ว่าจะแทรกหรือไม่ก็ตาม) โครงสร้างการค้นหาแบบไบนารีจะมีขนาดใหญ่เท่าที่จำเป็นเท่านั้น เป็น. นอกจากนี้เมื่อตารางแฮชต้องการพื้นที่มากขึ้นการขยายไปยังโครงสร้างอื่นอาจใช้เวลานาน แต่อาจขึ้นอยู่กับการนำไปใช้งาน
ต้นไม้ค้นหาไบนารีสามารถนำไปใช้กับอินเทอร์เฟซถาวรโดยที่ต้นไม้ใหม่จะถูกส่งคืน แต่ทรีเก่ายังคงมีอยู่ ดำเนินการอย่างระมัดระวังต้นไม้เก่าและใหม่ใช้ร่วมกันส่วนใหญ่ของโหนด คุณไม่สามารถทำได้ด้วยตารางแฮชมาตรฐาน
ต้นไม้ไบนารีจะค้นหาและแทรกเข้าไปได้ช้ากว่า แต่มีคุณสมบัติที่ดีมากของการข้ามผ่าน infix ซึ่งโดยพื้นฐานแล้วหมายความว่าคุณสามารถวนซ้ำผ่านโหนดของต้นไม้ตามลำดับที่เรียงลำดับได้
การทำซ้ำรายการของตารางแฮชไม่ได้มีเหตุผลมากนักเพราะมันกระจัดกระจายอยู่ในหน่วยความจำทั้งหมด
จากCracking the Coding Interview, 6th Edition
เราสามารถใช้ตารางแฮชกับแผนผังการค้นหาไบนารีที่สมดุล (BST) สิ่งนี้ทำให้เรามีเวลาค้นหา O (log n) ข้อดีของสิ่งนี้คืออาจใช้พื้นที่น้อยลงเนื่องจากเราไม่ได้จัดสรรอาร์เรย์ขนาดใหญ่อีกต่อไป นอกจากนี้เรายังสามารถวนซ้ำผ่านคีย์ตามลำดับซึ่งอาจมีประโยชน์ในบางครั้ง
BST ยังมีการดำเนินการ "findPred Prior" และ "findSuccessor" (เพื่อค้นหาองค์ประกอบที่เล็กที่สุดและใหญ่ที่สุดถัดไป) ในเวลา O (logn) ซึ่งอาจมีประโยชน์มาก Hash Table ไม่สามารถให้ประสิทธิภาพในเวลานั้นได้
หากคุณต้องการเข้าถึงข้อมูลในลักษณะที่เรียงลำดับรายการที่เรียงลำดับจะต้องได้รับการดูแลควบคู่ไปกับตารางแฮช ตัวอย่างที่ดีคือ Dictionary ใน. Net (ดูhttp://msdn.microsoft.com/en-us/library/3fcwy8h6.aspx )
สิ่งนี้มีผลข้างเคียงไม่เพียง แต่ทำให้เม็ดมีดช้าลงเท่านั้น แต่ยังใช้หน่วยความจำจำนวนมากกว่า b-tree
นอกจากนี้เนื่องจากมีการจัดเรียง b-tree จึงเป็นเรื่องง่ายที่จะค้นหาช่วงของผลลัพธ์หรือดำเนินการสหภาพหรือรวม
นอกจากนี้ยังขึ้นอยู่กับการใช้งาน Hash อนุญาตให้ค้นหาการจับคู่แบบตรงทั้งหมด หากคุณต้องการค้นหาช่วง BST คือตัวเลือก สมมติว่าคุณมีข้อมูลจำนวนมาก e1, e2, e3 ..... en
ด้วยตารางแฮชคุณสามารถค้นหาองค์ประกอบใด ๆ ในเวลาคงที่
หากคุณต้องการค้นหาค่าช่วงที่มากกว่า e41 และน้อยกว่า e8 BST สามารถค้นหาได้อย่างรวดเร็ว
สิ่งสำคัญคือฟังก์ชันแฮชที่ใช้เพื่อหลีกเลี่ยงการปะทะกัน แน่นอนว่าเราไม่สามารถหลีกเลี่ยงการปะทะกันได้ทั้งหมดซึ่งในกรณีนี้เราใช้วิธีการล่ามโซ่หรือวิธีอื่น ๆ ทำให้การดึงข้อมูลไม่ใช่เวลาคงที่อีกต่อไปในกรณีที่เลวร้ายที่สุด
เมื่อเต็มแล้วตารางแฮชจะต้องเพิ่มขนาดถังและคัดลอกองค์ประกอบทั้งหมดอีกครั้ง นี่เป็นค่าใช้จ่ายเพิ่มเติมที่ไม่มีอยู่ใน BST
ตารางแฮชไม่เหมาะสำหรับการจัดทำดัชนี เมื่อคุณค้นหาช่วง BST จะดีกว่า นั่นเป็นเหตุผลว่าทำไมดัชนีฐานข้อมูลส่วนใหญ่จึงใช้ต้นไม้ B + แทน Hash Tables
ต้นไม้ค้นหาแบบไบนารีเป็นทางเลือกที่ดีในการติดตั้งพจนานุกรมหากคีย์มีลำดับรวม (คีย์เทียบเคียงกันได้) ที่กำหนดไว้และคุณต้องการเก็บรักษาข้อมูลการสั่งซื้อ
เนื่องจาก BST เก็บรักษาข้อมูลการสั่งซื้อจึงมีการดำเนินการชุดไดนามิกเพิ่มเติมสี่ชุดที่ไม่สามารถดำเนินการได้ (อย่างมีประสิทธิภาพ) โดยใช้ตารางแฮช การดำเนินการเหล่านี้คือ:
การดำเนินการทั้งหมดนี้เหมือนกับการดำเนินการ BST ทุกครั้งมีความซับซ้อนของเวลา O (H) นอกจากนี้คีย์ที่เก็บไว้ทั้งหมดจะยังคงถูกจัดเรียงใน BST ดังนั้นจึงช่วยให้คุณสามารถรับลำดับคีย์ที่เรียงลำดับได้เพียงแค่ข้ามต้นไม้ตามลำดับ
โดยสรุปหากสิ่งที่คุณต้องการคือการแทรกการดำเนินการลบและลบตารางแฮชจะไม่สามารถเอาชนะได้ (โดยส่วนใหญ่) ในด้านประสิทธิภาพ แต่ถ้าคุณต้องการดำเนินการใด ๆ หรือทั้งหมดที่ระบุไว้ข้างต้นคุณควรใช้ BST โดยเฉพาะอย่างยิ่ง BST ที่ปรับสมดุลในตัวเอง
ข้อได้เปรียบหลักของตารางแฮชคือทำเกือบทั้งหมดใน ~ = O (1) และง่ายต่อการเข้าใจและนำไปใช้ จะแก้ปัญหา "สัมภาษณ์" ได้อย่างมีประสิทธิภาพ ดังนั้นหากคุณต้องการถอดรหัสการสัมภาษณ์การเขียนโค้ดให้หาเพื่อนที่ดีที่สุดด้วยตารางแฮช ;-)
แฮชแมปคือชุดอาร์เรย์ที่เชื่อมโยงกัน ดังนั้นอาร์เรย์ของค่าอินพุตของคุณจะรวมกันเป็นที่เก็บข้อมูล ในรูปแบบการกำหนดแอดเดรสแบบเปิดคุณจะมีตัวชี้ไปที่ที่เก็บข้อมูลและทุกครั้งที่คุณเพิ่มค่าใหม่ลงในที่เก็บข้อมูลคุณจะพบว่าในที่เก็บข้อมูลมีพื้นที่ว่างอยู่ที่ไหน มีสองสามวิธีในการดำเนินการนี้ - คุณเริ่มต้นที่จุดเริ่มต้นของที่เก็บข้อมูลและเพิ่มตัวชี้ในแต่ละครั้งและทดสอบว่ามีอยู่หรือไม่ สิ่งนี้เรียกว่าการตรวจสอบเชิงเส้น จากนั้นคุณสามารถทำการค้นหาแบบไบนารีเช่นเพิ่มซึ่งคุณจะเพิ่มความแตกต่างเป็นสองเท่าระหว่างจุดเริ่มต้นของที่เก็บข้อมูลและจุดที่คุณเพิ่มขึ้นหรือถอยหลังเป็นสองเท่าในแต่ละครั้งที่คุณค้นหาพื้นที่ว่าง สิ่งนี้เรียกว่าการตรวจสอบกำลังสอง ตกลง. ตอนนี้ปัญหาในทั้งสองวิธีนี้คือหากที่เก็บข้อมูลล้นไปยังที่อยู่ที่เก็บข้อมูลถัดไปคุณจะต้อง -
ตกลง. แต่ถ้าคุณใช้ลิงค์ลิสต์ก็ไม่น่าจะมีปัญหาใช่ไหม ใช่ในรายการที่เชื่อมโยงคุณไม่มีปัญหานี้ พิจารณาแต่ละที่เก็บข้อมูลเพื่อเริ่มต้นด้วยรายการที่เชื่อมโยงและหากคุณมี 100 องค์ประกอบในที่เก็บข้อมูลคุณจะต้องสำรวจ 100 องค์ประกอบเหล่านั้นเพื่อไปยังจุดสิ้นสุดของรายการที่เชื่อมโยงดังนั้นรายการเพิ่ม (องค์ประกอบ E) จะใช้เวลาในการ -
ข้อดีของการใช้งาน linkedlist คือคุณไม่จำเป็นต้องมีการดำเนินการจัดสรรหน่วยความจำและ O (N) การถ่ายโอน / สำเนาของที่เก็บข้อมูลทั้งหมดเช่นเดียวกับในกรณีของการใช้งานที่อยู่แบบเปิด
ดังนั้นวิธีลดการดำเนินการ O (N) ให้เล็กที่สุดคือการแปลงการนำไปใช้งานเป็นโครงสร้างการค้นหาแบบไบนารีโดยที่การดำเนินการค้นหาคือ O (log (N)) และคุณเพิ่มองค์ประกอบในตำแหน่งตามค่าของมัน คุณสมบัติเพิ่มเติมของ BST คือมันมาเรียง!
ต้นไม้ค้นหาแบบไบนารีจะเร็วกว่าเมื่อใช้กับคีย์สตริง โดยเฉพาะอย่างยิ่งเมื่อสตริงมีความยาว
ต้นไม้ค้นหาแบบไบนารีโดยใช้การเปรียบเทียบน้อยกว่า / มากกว่าซึ่งเร็วสำหรับสตริง (เมื่อไม่เท่ากัน) ดังนั้น BST สามารถตอบได้อย่างรวดเร็วเมื่อไม่พบสตริง เมื่อพบแล้วจะต้องทำการเปรียบเทียบแบบเต็มเพียงครั้งเดียว
ในตารางแฮช คุณต้องคำนวณแฮชของสตริงซึ่งหมายความว่าคุณต้องอ่านไบต์ทั้งหมดอย่างน้อยหนึ่งครั้งเพื่อคำนวณแฮช จากนั้นอีกครั้งเมื่อพบรายการที่ตรงกัน