ทำไมไพ ธ อนจึงใช้ตารางแฮชในการนำดิจิตัลมาใช้ แต่ไม่ใช่ต้นไม้สีแดงดำ [ปิด]


11

ทำไมไพ ธ อนจึงใช้ตารางแฮชในการนำดิจิตัลมาใช้ แต่ไม่ใช่ต้นไม้สีแดงดำ

กุญแจคืออะไร? ประสิทธิภาพ?


2
ที่ใช้ร่วมกันวิจัยของคุณช่วยให้ทุกคน บอกเราว่าคุณได้ลองทำอะไรและทำไมมันถึงไม่ตรงกับความต้องการของคุณ สิ่งนี้แสดงให้เห็นว่าคุณใช้เวลาในการพยายามช่วยตัวเองมันช่วยให้เราไม่ต้องย้ำคำตอบที่ชัดเจนและส่วนใหญ่จะช่วยให้คุณได้คำตอบที่เฉพาะเจาะจงและเกี่ยวข้องมากขึ้น ดูวิธีถาม
gnat

คำตอบ:


16

นี่เป็นคำตอบทั่วไปที่ไม่ได้เจาะจงเฉพาะงูหลาม

การเปรียบเทียบความซับซ้อนของอัลกอริทึม

       | Hash Table  |   Red-Black Tree    |
-------+-------------+---------------------+
Space  | O(n) : O(n) | O(n)     : O(n)     |
Insert | O(1) : O(n) | O(log n) : O(log n) |
Fetch  | O(1) : O(n) | O(log n) : O(log n) |
Delete | O(1) : O(n) | O(log n) : O(log n) |
       | avg  :worst | average  : worst    |

ปัญหาเกี่ยวกับตารางแฮชคือแฮชสามารถชนกันได้ มีกลไกต่าง ๆ ในการแก้ไขการชนเช่นการเปิดที่อยู่หรือการผูกมัดแยก กรณีที่เลวร้ายที่สุดอย่างแน่นอนคือกุญแจทั้งหมดมีรหัสแฮชเดียวกันซึ่งในกรณีนี้ตารางแฮชจะลดลงในรายการที่เชื่อมโยง

ในกรณีอื่น ๆ ตารางแฮชเป็นโครงสร้างข้อมูลที่ยอดเยี่ยมซึ่งง่ายต่อการติดตั้งและให้ประสิทธิภาพที่ดี ข้อเสียคือการใช้งานที่สามารถขยายตารางได้อย่างรวดเร็วและกระจายรายการของพวกเขาอาจจะเสียหน่วยความจำเกือบเท่าที่มีการใช้งานจริง

RB-Trees เป็นการปรับสมดุลตนเองและไม่เปลี่ยนความซับซ้อนของอัลกอริทึมในกรณีที่เลวร้ายที่สุด อย่างไรก็ตามพวกเขายากที่จะใช้ ความซับซ้อนเฉลี่ยของพวกเขานั้นแย่กว่าของตารางแฮช

ข้อ จำกัด สำหรับคีย์

ปุ่มทั้งหมดในตารางแฮชจะต้องสามารถแฮชและเปรียบเทียบได้เพื่อความเท่าเทียมกัน นี่เป็นเรื่องง่ายโดยเฉพาะอย่างยิ่งสำหรับสตริงหรือจำนวนเต็ม แต่ก็ค่อนข้างตรงไปตรงมาเพื่อขยายไปยังประเภทที่ผู้ใช้กำหนด ในบางภาษาเช่น Java คุณสมบัติเหล่านี้รับประกันโดยการกำหนด

คีย์ใน RB-Tree ต้องมีลำดับทั้งหมด: แต่ละคีย์จะต้องเปรียบเทียบกับคีย์อื่น ๆ และทั้งสองคีย์จะต้องเปรียบเทียบขนาดเล็กกว่าใหญ่กว่าหรือเท่ากัน ความเท่าเทียมกันในการสั่งซื้อนี้จะต้องเทียบเท่ากับความเท่าเทียมกันทางความหมาย นี่เป็นเรื่องตรงไปตรงมาสำหรับจำนวนเต็มและตัวเลขอื่น ๆ เช่นกันค่อนข้างง่ายสำหรับสตริง (คำสั่งต้องมีความสอดคล้องและไม่สามารถสังเกตได้จากภายนอกดังนั้นคำสั่งไม่จำเป็นต้องพิจารณาตำแหน่งที่ตั้ง[1] ) แต่ยากสำหรับประเภทอื่น ๆ ที่ไม่มีคำสั่งโดยธรรมชาติ . เป็นไปไม่ได้อย่างแน่นอนที่จะมีกุญแจประเภทต่าง ๆ เว้นแต่จะมีการเปรียบเทียบกันระหว่างพวกเขา

[1]: อันที่จริงฉันผิดตรงนี้ สองสตริงอาจไม่เท่ากับไบต์ แต่ยังคงเทียบเท่าตามกฎของบางภาษา ดูตัวอย่างการปรับสภาพ Unicode ให้เป็นตัวอย่างสำหรับตัวอย่างหนึ่งซึ่งมีการเข้ารหัสสตริงที่เท่ากันสองสายที่ต่างกัน การจัดองค์ประกอบอักขระ Unicode สำคัญกับแป้นแฮชของคุณหรือไม่เป็นสิ่งที่การใช้ตารางแฮชไม่สามารถรู้ได้

บางคนอาจคิดว่าโซลูชันราคาถูกสำหรับปุ่ม RB-Tree จะเป็นการทดสอบความเท่าเทียมกันก่อนจากนั้นจึงทำการเปรียบเทียบตัวตน (เช่นเปรียบเทียบตัวชี้) อย่างไรก็ตามการสั่งซื้อนี้จะไม่ส่งผ่าน: ถ้าa == bและid(a) > id(c)จากนั้นจะต้องปฏิบัติตามid(b) > id(c)เช่นกันซึ่งไม่ได้รับประกันที่นี่ ดังนั้นเราอาจใช้รหัสแฮชของคีย์เป็นคีย์ค้นหา ที่นี่การสั่งซื้อทำงานได้อย่างถูกต้อง แต่เราอาจสิ้นสุดด้วยคีย์ที่แตกต่างกันหลายรหัสที่มีรหัสแฮชเดียวกันซึ่งจะถูกกำหนดให้กับโหนดเดียวกันในทรี RB ในการแก้ปัญหาการแฮชเหล่านี้เราสามารถใช้การโยงแบบแยกกันเช่นเดียวกับตารางแฮช

ด้านอื่น ๆ

  • ฉันคาดหวังให้ตารางแฮชมีตำแหน่งหน่วยความจำดีกว่าต้นไม้เนื่องจากตารางแฮชเป็นเพียงอาร์เรย์

  • รายการในโครงสร้างข้อมูลทั้งสองมีค่าใช้จ่ายค่อนข้างสูง:

    • ตารางแฮช: คีย์ค่าและตัวชี้รายการถัดไปในกรณีของการโยงแบบแยก การจัดเก็บรหัสแฮชสามารถปรับขนาดได้เร็วขึ้น
    • RB-tree: คีย์, ค่า, สี, ตัวชี้เด็กซ้าย, ตัวชี้เด็กขวา โปรดทราบว่าในขณะที่สีเป็นบิตเดียวปัญหาการจัดตำแหน่งอาจหมายความว่าคุณยังคงเปลืองเนื้อที่เพียงพอสำหรับตัวชี้เกือบทั้งหมดหรือแม้กระทั่งตัวชี้เกือบสี่ตัวเมื่อมีการจัดสรรบล็อกหน่วยความจำขนาด power-of-two เท่านั้น ไม่ว่าในกรณีใดรายการ RB-tree จะใช้หน่วยความจำมากกว่ารายการตารางแฮช
  • การแทรกและการลบใน RB-tree เกี่ยวข้องกับการหมุนของต้นไม้ สิ่งเหล่านี้ไม่ได้มีราคาแพง แต่เกี่ยวข้องกับค่าใช้จ่าย ในแฮชการแทรกและการลบไม่แพงไปกว่าการเข้าถึงแบบง่าย ๆ (แม้ว่าการปรับขนาดตารางแฮชตามการแทรกนั้นเป็นO(n)ความพยายาม)

  • ตารางแฮชสามารถเปลี่ยนแปลงได้โดยเนื้อแท้ในขณะที่ RB-tree สามารถนำไปใช้ในรูปแบบที่ไม่เปลี่ยนรูป อย่างไรก็ตามสิ่งนี้ไม่ค่อยมีประโยชน์


เราสามารถมีตารางแฮชที่มีต้น RB เล็ก ๆ สำหรับการชนกันของแฮชได้หรือไม่?
aragaer

@aragaer ไม่ใช่โดยทั่วไป แต่อาจเป็นไปได้ในบางกรณี อย่างไรก็ตามการชนกันมักจะจัดการโดยรายการที่เชื่อมโยง - ง่ายต่อการใช้งานมากน้อยกว่าค่าใช้จ่ายมากและมักจะมีประสิทธิภาพมากกว่าเพราะเรามักจะมีการชนกันน้อยมาก หากเราคาดหวังการชนหลายครั้งเราสามารถเปลี่ยนฟังก์ชันแฮชหรือใช้ทรี B ที่ง่ายกว่า ต้นไม้ที่มีความสมดุลในตัวเองเช่นต้นไม้ RB นั้นยอดเยี่ยม แต่มีหลายกรณีที่ต้นไม้เหล่านั้นไม่เพิ่มมูลค่า
amon

ต้นไม้ต้องการวัตถุที่รองรับ "<" ตารางแฮชต้องการวัตถุที่สนับสนุนแฮช + "=" ดังนั้นต้นไม้ RB อาจเป็นไปไม่ได้ แต่จริงๆแล้วถ้าตารางแฮชของคุณมีการชนจำนวนมากคุณต้องใช้ฟังก์ชันแฮชใหม่ไม่ใช่อัลกอริธึมทางเลือกสำหรับการชนคีย์
gnasher729

1

มีสาเหตุหลายประการที่อาจเป็นจริง แต่เหตุผลหลัก ๆ น่าจะเป็น:

  • ตารางแฮชง่ายกว่าการนำไปใช้กับต้นไม้ ทั้งสองมีความสำคัญเล็กน้อย แต่ตารางแฮชง่ายกว่าเล็กน้อยและผลกระทบต่อโดเมนของคีย์ทางกฎหมายนั้นเข้มงวดน้อยกว่าเพราะคุณเพียงแค่ต้องการฟังก์ชั่นการแฮชและฟังก์ชั่นความเท่าเทียม ต้นไม้ต้องการฟังก์ชั่นการสั่งซื้อทั้งหมดและมันยากที่จะเขียน
  • ตารางแฮช (อาจ) มีประสิทธิภาพที่ดีขึ้นในขนาดเล็ก เรื่องนี้มีความสำคัญมากเนื่องจากมีส่วนสำคัญของงานที่เกี่ยวกับชุดข้อมูลขนาดใหญ่เท่านั้น ในทางปฏิบัติส่วนใหญ่ใช้งานได้จริงกับปุ่มเพียงสิบหรือหลายร้อยปุ่มเท่านั้น ประสิทธิภาพขนาดเล็กมีความสำคัญมากและคุณไม่สามารถใช้การวิเคราะห์เชิงเส้นกำกับเพื่อหาสิ่งที่ดีที่สุดที่นั่น คุณต้องใช้จริงและวัด

ง่ายกว่าในการเขียน / ดูแลรักษาและเป็นผู้ชนะในการใช้งานทั่วไป ลงทะเบียนได้โปรด!

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.