โครงสร้างข้อมูลที่รู้จักกันน้อย แต่มีประโยชน์คืออะไร


795

มีบางโครงสร้างข้อมูลที่มีประโยชน์จริง ๆ แต่ไม่รู้จักโปรแกรมเมอร์ส่วนใหญ่ อันไหนกันนะ?

ทุกคนรู้เกี่ยวกับรายการที่เชื่อมโยงต้นไม้ไบนารีและแฮช แต่ตัวอย่างเช่นรายการข้ามและตัวกรองบลูม ฉันอยากจะรู้โครงสร้างข้อมูลเพิ่มเติมที่ไม่ธรรมดา แต่ก็คุ้มค่าที่จะรู้เพราะพวกเขาพึ่งพาความคิดที่ดีและเพิ่มกล่องเครื่องมือของโปรแกรมเมอร์

PS: ฉันยังสนใจในเทคนิคต่าง ๆ เช่นการเชื่อมโยงการเต้นรำซึ่งใช้ประโยชน์อย่างชาญฉลาดของคุณสมบัติของโครงสร้างข้อมูลทั่วไป

แก้ไข : โปรดพยายามรวมลิงค์ไปยังหน้าที่อธิบายโครงสร้างข้อมูลโดยละเอียด นอกจากนี้ลองเพิ่มคำสองสามคำเกี่ยวกับสาเหตุที่โครงสร้างข้อมูลเย็น (ดังที่Jonas Kölkerชี้ไปแล้ว) นอกจากนี้ยังพยายามที่จะให้ข้อมูลหนึ่งโครงสร้างต่อคำตอบ สิ่งนี้จะช่วยให้โครงสร้างข้อมูลที่ดีขึ้นสามารถลอยขึ้นไปด้านบนได้จากการโหวตของพวกเขาเพียงอย่างเดียว


คำตอบ:


271

ความพยายามยังเป็นที่รู้จักกันในนามคำนำหน้าต้นไม้หรือต้นไม้crit บิตมีมานานกว่า 40 ปี แต่ก็ยังไม่ทราบ การใช้ความพยายามอย่างยอดเยี่ยมอธิบายไว้ใน " ถังขยะ - โครงสร้างข้อมูล LC-trie และแฮชแบบไดนามิก " ซึ่งรวมฟังก์ชัน trie กับฟังก์ชันแฮช


12
ใช้กันอย่างแพร่หลายมากโดยเครื่องตรวจตัวสะกด
Steven A. Lowe

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

โปรแกรม regex ใน Perl 5.10 จะสร้างความพยายามโดยอัตโนมัติ
Brad Gilbert

จากประสบการณ์ของฉันพยายามอย่างเจ็บปวดราคาแพงเนื่องจากตัวชี้โดยทั่วไปจะยาวกว่าตัวถ่านซึ่งเป็นความอัปยศ มันเหมาะสำหรับชุดข้อมูลบางอย่างเท่านั้น
Joe

18
เนื่องจากไม่มีคำถาม SO โดยไม่คำนึงถึงหัวข้อนั้นเสร็จสมบูรณ์โดยไม่มีใครพูดถึง jQuery .... John Resig ผู้สร้าง jQuery มีชุดโครงสร้างข้อมูลที่น่าสนใจของโพสต์ที่เขาดูการใช้งานของ Trie ต่าง ๆ : ejohn.org/blog/
modified

231

Bloom filter : อาร์เรย์บิตของmบิตโดยเริ่มต้นทั้งหมดตั้งค่าเป็น 0

ในการเพิ่มไอเท็มที่คุณเรียกใช้ผ่านฟังก์ชั่นแฮชkที่จะให้ดัชนีkในอาเรย์ที่คุณตั้งค่าเป็น 1

ในการตรวจสอบว่ารายการนั้นอยู่ในชุดหรือไม่ให้คำนวณดัชนีkและตรวจสอบว่ารายการนั้นถูกตั้งค่าเป็น 1 หรือไม่

แน่นอนว่าสิ่งนี้ให้ความน่าจะเป็นของการบวกเท็จ (ตามวิกิพีเดียประมาณ 0.61 ^ (m / n) โดยที่ n คือจำนวนรายการที่แทรก) ไม่สามารถลบเท็จได้

การลบรายการนั้นเป็นไปไม่ได้ แต่คุณสามารถใช้ตัวกรองการนับ Bloomซึ่งแสดงโดยอาร์เรย์ของ ints และการเพิ่ม / ลดลง


20
คุณลืมที่จะพูดถึงการใช้งานของพวกเขาด้วยพจนานุกรม :) คุณสามารถบีบพจนานุกรมเต็มรูปแบบเป็นตัวกรองบานมีประมาณ 512k เช่น Hashtable โดยไม่มีค่า
คริสเอส

8
Google อ้างถึงการใช้ตัวกรอง Bloom ในการใช้งาน BigTable
Brian Gianforcaro

16
@FreshCode จริง ๆ แล้วมันช่วยให้คุณสามารถทดสอบการขาดองค์ประกอบในชุดได้อย่างถูกต้องเนื่องจากคุณสามารถรับผลบวกปลอม แต่ไม่เคยปฏิเสธเชิงลบ
Tom Savage

26
@FreshCode ตามที่ @ Tom Savage กล่าวว่ามีประโยชน์มากขึ้นเมื่อตรวจสอบเชิงลบ ตัวอย่างเช่นคุณสามารถใช้มันเป็นตัวตรวจสอบการสะกดได้อย่างรวดเร็วและเล็ก (ในแง่ของการใช้หน่วยความจำ) เพิ่มคำทั้งหมดลงไปจากนั้นลองค้นหาคำที่ผู้ใช้ป้อน หากคุณได้รับค่าลบหมายความว่ามันสะกดผิด จากนั้นคุณสามารถเรียกใช้การตรวจสอบที่มีราคาแพงกว่าเพื่อค้นหาการแข่งขันที่ใกล้เคียงที่สุดและเสนอการแก้ไข
lacop

5
@ abhin4v: ตัวกรองบลูมมักใช้เมื่อคำขอส่วนใหญ่มีแนวโน้มที่จะส่งคืนคำตอบของ "ไม่" (เช่นกรณีที่นี่) ซึ่งหมายความว่าสามารถตรวจสอบคำตอบ "ใช่" จำนวนเล็กน้อยด้วยการทดสอบที่ช้าลง สิ่งนี้ยังส่งผลให้เวลาตอบสนองแบบสอบถามโดยเฉลี่ยลดลงอย่างมาก ไม่ทราบว่า Safe Browsing ของ Chrome ทำเช่นนั้นหรือไม่
j_random_hacker

140

Rope : มันคือสตริงที่อนุญาตให้มีการผสมแบบราคาถูกซับสเตรตการแทรกกลางและการต่อท้าย ฉันเคยใช้มันครั้งเดียวเท่านั้น แต่ไม่มีโครงสร้างอื่นใดที่พอเพียง สตริงและอาเรย์ทั่วไปที่เตรียมไว้มีราคาแพงเกินไปสำหรับสิ่งที่เราต้องทำ


ฉันมีความคิดบางอย่างเช่นนี้สำหรับการใช้งานของฉันเอง ดีใจที่ได้ทราบว่ามีการใช้งานที่อื่นแล้ว
Kibbee

15
มีการดำเนินการใน STL เอสจีไอ (1998) เป็น: sgi.com/tech/stl/Rope.html
ควาร์ก

2
เมื่อไม่นานมานี้ฉันได้เขียนบางสิ่งที่คล้ายคลึงกับ Java - ประสิทธิภาพยอดเยี่ยม: code.google.com/p/mikeralib/source/browse/trunk/Mikera/src/ …
mikera

เชือกเป็นของหายากสวย: stackoverflow.com/questions/1863440/...
Will

6
การเชื่อมโยง Mikera คือค้างที่นี่เป็นปัจจุบัน
aptwebapps

128

รายการข้ามค่อนข้างเรียบร้อย

Wikipedia
รายการข้ามเป็นโครงสร้างข้อมูลที่น่าจะเป็นไปตามหลายขนานรายการเรียงโยงเชื่อมโยงที่มีประสิทธิภาพเทียบเท่ากับต้นไม้ค้นหาไบนารี (บันทึกการสั่งซื้อ n เวลาเฉลี่ยสำหรับการดำเนินงานส่วนใหญ่)

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

หากคุณต้องการได้รับการแนะนำในเชิงลึกเกี่ยวกับการข้ามรายการที่นี่เป็นลิงค์ไปยังวิดีโอของ Introduction to Algorithms บรรยายเกี่ยวกับพวกเขา

นอกจากนี้ที่นี่เป็นแอปเพล็ต Java ที่แสดงการข้ามรายการด้วยสายตา


+1 Qt ใช้ skip list แทน RB-trees สำหรับแผนที่และเซตที่เรียงลำดับแล้ว ใช่พวกเขาดี (ในภาษาที่จำเป็นต่อไป)
Michael Ekstrand

2
Redis ใช้รายการข้ามเพื่อใช้ "ชุดที่เรียงลำดับ"
antirez

รายการข้ามอาจเป็นโครงสร้างข้อมูลที่ฉันโปรดปรานที่จะใช้เมื่อฉันต้องการโครงสร้างข้อมูลที่ดีและฉันไม่รับประกันว่าจะเรียงตามลำดับของข้อมูลและฉันต้องการการใช้งานที่ง่ายกว่าโครงสร้างข้อมูล "สมดุล" อื่น ๆ ช่างเป็นเรื่องที่ดี
earino

หมายเหตุด้านข้างที่น่าสนใจ: หากคุณเพิ่มระดับให้เพียงพอในรายการข้ามของคุณคุณจะต้องจบลงด้วยต้นไม้ B
Riyad Kalla

92

ดัชนีเชิงพื้นที่โดยเฉพาะอย่างยิ่งR-treesและKD-treesจัดเก็บข้อมูลเชิงพื้นที่อย่างมีประสิทธิภาพ เหมาะสำหรับข้อมูลพิกัดทางภูมิศาสตร์แผนที่และตำแหน่งของ VLSI และอัลกอริธึมเส้นทางและบางครั้งสำหรับการค้นหาเพื่อนบ้านที่ใกล้ที่สุด

Bit Arraysเก็บบิตแต่ละส่วนไว้อย่างแน่นหนาและอนุญาตให้ใช้งานบิตเร็วได้


6
ดัชนีเชิงพื้นที่ยังมีประโยชน์สำหรับการจำลองร่างกาย N ที่เกี่ยวข้องกับแรงระยะยาวเช่นแรงโน้มถ่วง
Justin Peel

87

Zippers - อนุพันธ์ของโครงสร้างข้อมูลที่ปรับเปลี่ยนโครงสร้างให้มีความคิดตามธรรมชาติของ 'เคอร์เซอร์' - ตำแหน่งปัจจุบัน สิ่งเหล่านี้มีประโยชน์จริง ๆ เนื่องจากเป็นการรับประกันว่าเครื่องบ่งชี้ไม่สามารถใช้งานไม่ได้เช่นในเครื่องมือจัดการหน้าต่าง xmonadเพื่อติดตามว่าหน้าต่างใดได้โฟกัส

น่าอัศจรรย์คุณสามารถได้มาโดยใช้เทคนิคจากแคลคูลัสกับประเภทของโครงสร้างข้อมูลดั้งเดิม!


2
สิ่งนี้มีประโยชน์ในการเขียนโปรแกรมใช้งานได้ (ในภาษาที่จำเป็นเท่านั้นที่คุณเก็บตัวชี้หรือดัชนีไว้) นอกจากนี้ฉันยังไม่เข้าใจว่า Zippers ทำงานอย่างไร
Stefan Monov

4
@tefan ประเด็นก็คือว่าคุณไม่จำเป็นต้องเก็บดัชนีหรือตัวชี้แยกต่างหากในขณะนี้
Don Stewart

69

นี่คือบางส่วน:

  • คำต่อท้ายพยายาม มีประโยชน์สำหรับการค้นหาสตริงเกือบทุกประเภท (http://en.wikipedia.org/wiki/Suffix_trie#Functionality ) ดูเพิ่มเติมอาร์เรย์ต่อท้าย; พวกมันไม่เร็วเท่ากับต้นต่อท้าย แต่มีขนาดเล็กกว่ามาก

  • Splay trees (ดังที่ได้กล่าวไว้แล้ว) เหตุผลที่พวกเขาเจ๋งคือสามเท่า:

    • มันมีขนาดเล็ก: คุณต้องการเพียงพอยน์เตอร์ซ้ายและขวาเหมือนที่คุณทำในต้นไม้ไบนารีใด ๆ (ไม่จำเป็นต้องเก็บข้อมูลสีโหนดหรือขนาด)
    • มันค่อนข้างง่ายต่อการนำไปใช้
    • พวกเขามีความซับซ้อนตัดจำหน่ายที่เหมาะสมที่สุดสำหรับโฮสต์ทั้งหมดของ "เกณฑ์การวัด" (เวลาค้นหา logn เป็นคนที่ทุกคนรู้) ดูhttp://en.wikipedia.org/wiki/Splay_tree#Performance_theorems
  • กองค้นหาต้นไม้ที่สั่งซื้อ: คุณเก็บคู่ (คีย์, prio) ไว้ในต้นไม้หนึ่งต้นซึ่งเป็นต้นไม้ค้นหาที่เกี่ยวกับกุญแจและจัดลำดับกองไว้ตามลำดับความสำคัญ หนึ่งสามารถแสดงให้เห็นว่าต้นไม้ดังกล่าวมีรูปร่างที่ไม่ซ้ำกัน (และมันไม่ได้บรรจุอย่างเต็มที่เสมอไปทางซ้าย) ด้วยการจัดลำดับความสำคัญแบบสุ่มจะช่วยให้คุณคาดหวังเวลาค้นหา O (บันทึก n), IIRC

  • Niche หนึ่งคือรายการ adjacency สำหรับกราฟระนาบที่ไม่ได้บอกทิศทางด้วย O (1) เคียวรีเพื่อนบ้าน นี่ไม่ใช่โครงสร้างข้อมูลเป็นวิธีเฉพาะในการจัดระเบียบโครงสร้างข้อมูลที่มีอยู่ นี่คือวิธีที่คุณทำ: กราฟระนาบทุกตัวมีโหนดที่มีระดับไม่เกิน 6 จุดเลือกโหนดดังกล่าววางเพื่อนบ้านไว้ในรายการเพื่อนบ้านลบออกจากกราฟและเรียกคืนจนกว่ากราฟจะว่างเปล่า เมื่อได้รับคู่ (u, v) ให้มองหา u ในรายชื่อเพื่อนบ้านของ v และหา v ในรายชื่อเพื่อนบ้านของ u ทั้งสองมีขนาดไม่เกิน 6 ดังนั้นนี่คือ O (1)

โดยอัลกอริทึมด้านบนหาก u และ v เป็นเพื่อนบ้านคุณจะไม่มี u ในรายการของ v และ v ในรายการของ u หากคุณต้องการสิ่งนี้เพียงเพิ่มเพื่อนบ้านที่หายไปของแต่ละโหนดลงในรายการเพื่อนบ้านของโหนดนั้น แต่เก็บจำนวนเพื่อนบ้านที่คุณต้องค้นหาเพื่อค้นหาอย่างรวดเร็ว


แผนภูมิการค้นหาที่สั่งซื้อแบบฮีปเรียกว่าแบบทรี เคล็ดลับอย่างหนึ่งที่คุณสามารถทำได้คือเปลี่ยนลำดับความสำคัญของโหนดเพื่อดันลงไปที่ด้านล่างของทรีเพื่อลบได้ง่ายขึ้น
paperhorse

1
"แผนผังค้นหาของกองที่เรียกว่า treap" - ในคำจำกัดความที่ฉันได้ยิน, IIRC, treap เป็นทรีค้นหาที่สั่งซื้อฮีปด้วยลำดับความสำคัญแบบสุ่ม คุณสามารถเลือกจัดลำดับความสำคัญอื่น ๆ ขึ้นอยู่กับการใช้งาน ...
โจนาส Kolker

2
Trieต่อท้ายนั้นเกือบจะ แต่ไม่เหมือนกับต้นไม้ต่อท้ายที่เย็นกว่ามากซึ่งมีสตริงและไม่มีตัวอักษรแต่ละตัวที่ขอบและสามารถสร้างได้ในเวลาเชิงเส้น (!) แม้จะช้ากว่า asymptotically ในทางปฏิบัติอาร์เรย์ส่วนต่อท้ายมักจะเร็วกว่าต้นไม้ต่อท้ายสำหรับงานหลายอย่างเนื่องจากมีขนาดเล็กลงและมีตัวชี้ทิศทางที่น้อยลง รักการค้นหากราฟบนดาวเคราะห์ O (1) BTW!
j_random_hacker

@j_random_hacker: อาร์เรย์ส่วนต่อท้ายจะไม่ช้าลงแบบ asymptotically นี่คือรหัส ~ 50 บรรทัดสำหรับการสร้างอาร์เรย์ต่อท้ายเชิงเส้น: cs.helsinki.fi/u/tpkarkka/publications/icalp03.pdf
Edward KMETT

1
@Edward Kmett: ฉันมีในความเป็นจริงอ่านกระดาษว่ามันก็ค่อนข้างก้าวหน้าในการต่อท้ายอาร์เรย์ก่อสร้าง (แม้ว่าจะทราบกันดีอยู่แล้วว่าการสร้างเวลาเชิงเส้นเป็นไปได้โดยการ "ผ่าน" ต้นไม้ต่อท้ายนี่เป็นขั้นตอนวิธีที่ 1 "โดยตรง" อย่างปฏิเสธไม่ได้ในทางปฏิบัติ) แต่การดำเนินการบางอย่างนอกการก่อสร้างยังคงช้าลง สร้างตาราง ซึ่งสามารถทำได้ใน O (n) แต่คุณสูญเสียขนาดและผลประโยชน์ในพื้นที่ของอาร์เรย์ส่วนต่อท้ายที่บริสุทธิ์โดยทำเช่นนั้น
j_random_hacker

65

ฉันคิดว่าทางเลือกที่ไม่มีล็อคกับโครงสร้างข้อมูลมาตรฐานเช่นคิวแบบไม่ล็อค, สแต็กและรายการถูกมองข้ามมาก
พวกเขามีความเกี่ยวข้องมากขึ้นเมื่อเห็นพ้องด้วยกันกลายเป็นลำดับความสำคัญที่สูงขึ้นและเป็นเป้าหมายที่น่าชื่นชมยิ่งกว่าการใช้ Mutexes หรือล็อคเพื่อจัดการอ่าน / เขียนพร้อมกัน

นี่คือลิงค์บางส่วนที่
http://www.cl.cam.ac.uk/research/srg/netos/lock-free/
http://www.research.ibm.com/people/m/michael/podc-1996.pdf [ลิงก์ไปยัง PDF]
http://www.boyet.com/Articles/LockfreeStack.html

บล็อกของ Mike Acton (บ่อยครั้งเป็นการยั่วยุ) มีบทความที่ยอดเยี่ยมเกี่ยวกับการออกแบบและวิธีการล็อคฟรี


ทางเลือกที่ปลอดล็อคมีความสำคัญในโลกปัจจุบันแบบ multi-core, ขนาน, ที่ปรับขนาดได้มาก :-)
earino

ผู้ทำลายส่วนใหญ่จะทำงานได้ดีขึ้นในกรณีส่วนใหญ่
deadalnix

55

ฉันคิดว่าDisjoint Setนั้นค่อนข้างดีสำหรับกรณีที่คุณต้องแบ่งรายการเป็นชุดที่แตกต่างกันและเป็นสมาชิกของแบบสอบถาม การใช้งานที่ดีของการดำเนินการของสหภาพและการค้นหาส่งผลให้ต้นทุนที่ตัดจำหน่ายมีค่าคงที่อย่างมีประสิทธิภาพ (การกลับกันของฟังก์ชันของ Ackermnan ถ้าฉันจำโครงสร้างข้อมูลของฉันได้อย่างถูกต้อง)


8
สิ่งนี้เรียกอีกอย่างว่า"โครงสร้างการค้นหาข้อมูลร่วม" ฉันตกตะลึงเมื่อแรกที่ฉันได้เรียนรู้เกี่ยวกับโครงสร้างข้อมูลที่ชาญฉลาดในคลาสอัลกอริทึม
BlueRaja - Danny Pflughoeft

ส่วนขยาย union-find-delete อนุญาตการลบแบบคงที่ได้เช่นกัน
Peaker

4
ฉันใช้ Disjoint Set สำหรับเครื่องกำเนิด Dungeon ของฉันเพื่อให้แน่ใจว่าทุกห้องสามารถเข้าถึงได้ด้วยทางเดิน :)
goldenratio

52

ฟีโบนักชีกอง

พวกมันถูกใช้ในอัลกอริทึมที่รู้จักกันเร็วที่สุดบางอย่าง (ไม่แสดงอาการ) สำหรับปัญหาที่เกี่ยวข้องกับกราฟมากมายเช่นปัญหาเส้นทางที่สั้นที่สุด อัลกอริทึมของ Dijkstra ทำงานในเวลา O (E log V) พร้อมกับไบนารีฮีปมาตรฐาน การใช้ Fibonacci heaps ปรับปรุงให้เป็น O (E + V log V) ซึ่งเป็นการเพิ่มความเร็วอย่างมากสำหรับกราฟที่หนาแน่น แต่น่าเสียดายที่พวกเขามีปัจจัยคงที่สูงมักทำให้พวกเขาไม่สามารถปฏิบัติได้จริง


ปัจจัยคงที่สูงอย่างที่คุณพูดและใช้งานได้ยากตามเพื่อนที่ต้อง ไม่เย็นเท่านี้ แต่ก็น่าจะคุ้มที่จะรู้
p4bl0

พวกเหล่านี้ทำให้พวกเขาสามารถแข่งขันได้เมื่อเทียบกับกองอื่น ๆ : cphstl.dk/Presentation/SEA2010/SEA-10.pdf มีโครงสร้างข้อมูลที่เกี่ยวข้องที่เรียกว่า Pairing Heaps ซึ่งง่ายต่อการใช้งาน อย่างไรก็ตามการวิเคราะห์เชิงทฤษฎีเปิดบางส่วน
มานูเอล

จากประสบการณ์ของฉันกับ Fibonacci heaps ฉันพบว่าการดำเนินการจัดสรรหน่วยความจำราคาแพงทำให้มีประสิทธิภาพน้อยกว่าฮีปไบนารีแบบง่าย ๆ ที่แบ็กอัพโดยอาเรย์
jutky

44

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

การแบ่งพื้นที่แบบไบนารี่ (BSP) เป็นวิธีการแบ่งพื้นที่แบบวนซ้ำแบบวนซ้ำโดยใช้ไฮเปอร์เพลน แผนกนี้จะทำให้เกิดการเป็นตัวแทนของฉากโดยใช้โครงสร้างข้อมูลต้นไม้ที่รู้จักกันในชื่อต้นไม้ BSP

กล่าวอีกนัยหนึ่งมันเป็นวิธีการแบ่งรูปหลายเหลี่ยมที่มีความซับซ้อนออกเป็นชุดนูนหรือรูปหลายเหลี่ยมขนาดเล็กที่ประกอบด้วยมุมที่ไม่สะท้อนทั้งหมด (มุมที่เล็กกว่า 180 °) สำหรับคำอธิบายทั่วไปเพิ่มเติมเกี่ยวกับการแบ่งพื้นที่ให้ดูที่การแบ่งพื้นที่

เดิมวิธีการนี้ถูกเสนอในกราฟิกคอมพิวเตอร์ 3 มิติเพื่อเพิ่มประสิทธิภาพการแสดงผล แอปพลิเคชั่นอื่น ๆ รวมถึงการปฏิบัติงานทางเรขาคณิตที่มีรูปร่าง (เรขาคณิตทึบเชิงสร้างสรรค์) ใน CAD, การตรวจจับการชนในหุ่นยนต์และเกมคอมพิวเตอร์สามมิติและแอปพลิเคชันคอมพิวเตอร์อื่น ๆ ที่เกี่ยวข้องกับการจัดการฉากอวกาศที่ซับซ้อน


... และ octrees และ kd-trees ที่เกี่ยวข้อง
Lloeki


38

ดูFinger Treesโดยเฉพาะอย่างยิ่งหากคุณเป็นแฟนของโครงสร้างข้อมูลที่กล่าวถึงก่อนหน้านี้ พวกมันเป็นตัวแทนการทำงานของลำดับถาวรที่สนับสนุนการเข้าถึงจุดสิ้นสุดในเวลาคงที่ที่ถูกตัดจำหน่ายและการต่อกันและแยกในเวลาลอการิทึมในขนาดของชิ้นเล็ก ๆ

ตามบทความต้นฉบับ :

การทำงาน 2-3 นิ้วต้นไม้ของเราเป็นตัวอย่างของเทคนิคการออกแบบทั่วไป troduced in-โดย Okasaki (1998) เรียกว่าส่อชะลอตัว recursive เราได้กล่าวแล้วว่าต้นไม้เหล่านี้เป็นส่วนขยายของโครงสร้าง deque โดยปริยายของเขาแทนที่คู่กับ 2-3 โหนดเพื่อให้ความยืดหยุ่นที่จำเป็นสำหรับการต่อข้อมูลที่มีประสิทธิภาพและการแยก

ต้นไม้ต้นสามารถกำหนดค่าพารามิเตอร์ด้วยmonoidและการใช้ monoids ที่แตกต่างกันจะส่งผลให้พฤติกรรมที่แตกต่างกันสำหรับต้นไม้ ซึ่งจะช่วยให้ Finger Trees จำลองโครงสร้างข้อมูลอื่น ๆ



ลองดูคำตอบที่ซ้ำกันนี้มันคุ้มค่าที่จะอ่าน!
Francois G

34

บัฟเฟอร์วงกลมหรือแหวน - ใช้สำหรับการสตรีมเหนือสิ่งอื่นใด


4
นอกจากนี้ยังน่ารังเกียจอย่างใดการจัดการที่จะได้รับการจดสิทธิบัตร (อย่างน้อยเมื่อใช้สำหรับวิดีโอ) ip.com/patent/USRE36801
David Eison

จากการอ่านลิงค์ฉันไม่คิดว่าโครงสร้างข้อมูลของตัวเองนั้นได้รับการจดสิทธิบัตร ฉันยอมรับว่านี่เป็นโครงสร้างข้อมูลที่ไม่ได้ใช้อย่างแน่นอน
แรงดึงดูด

33

ฉันประหลาดใจที่ไม่มีใครพูดถึงต้นไม้ Merkle (เช่น. Hash Trees )

ใช้ในหลายกรณี (โปรแกรม P2P ลายเซ็นดิจิทัล) ที่คุณต้องการตรวจสอบความถูกต้องของไฟล์ทั้งหมดเมื่อคุณมีไฟล์เพียงบางส่วนเท่านั้น


32

<zvrba> ต้นไม้ Van Emde-Boas

ฉันคิดว่ามันจะมีประโยชน์ที่จะรู้ว่าทำไมมันถึงเท่ห์ โดยทั่วไปคำถาม "ทำไม" เป็นสิ่งสำคัญที่สุดที่จะถาม;)

คำตอบของฉันคือพวกเขาให้พจนานุกรม O (log log n) พร้อมคีย์ {1..n} ซึ่งไม่ขึ้นอยู่กับจำนวนคีย์ที่ใช้งาน เช่นเดียวกับการแบ่งครึ่งซ้ำ ๆ จะช่วยให้คุณ O (log n) sqrting ซ้ำให้คุณ O (log log n) ซึ่งเป็นสิ่งที่เกิดขึ้นในต้นไม้ vEB


พวกเขาดีจากมุมมองทางทฤษฎี อย่างไรก็ตามในทางปฏิบัติมันค่อนข้างยากที่จะดึงประสิทธิภาพการแข่งขันออกมา กระดาษที่ฉันรู้ว่าทำให้พวกเขาทำงานได้ดีมากถึง 32 บิต ( citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.2.7403 ) แต่วิธีการนั้นจะไม่ขยายเกิน 34-35 บิตหรือ ดังนั้นและไม่มีการดำเนินการดังกล่าว
มานูเอล

อีกเหตุผลที่พวกเขาเท่ห์ก็คือพวกเขาเป็นหน่วยการสร้างที่สำคัญสำหรับอัลกอริธึมที่หลงลืมแคชจำนวนมาก
Edward KMETT


29

ตัวแปรที่น่าสนใจของตารางแฮชที่เรียกว่านกกาเหว่า Hashing มันใช้ฟังก์ชั่นแฮหลายฟังก์ชั่นแทนที่จะเป็นเพียง 1 เพื่อจัดการกับการชนกันของแฮช การชนได้รับการแก้ไขโดยการลบวัตถุเก่าออกจากตำแหน่งที่ระบุโดยแฮชหลักและย้ายไปยังตำแหน่งที่ระบุโดยฟังก์ชันแฮชสำรอง Cuckoo Hashing ช่วยให้การใช้พื้นที่หน่วยความจำมีประสิทธิภาพมากขึ้นเพราะคุณสามารถเพิ่มตัวประกอบภาระของคุณได้สูงถึง 91% ด้วยฟังก์ชันแฮชเพียง 3 ฟังก์ชันและยังมีเวลาเข้าถึงที่ดี


5
ตรวจสอบ hopscotch hashing ที่อ้างว่าเร็วขึ้น
chmike

27

กองนาทีสูงสุดเป็นรูปแบบของที่กองที่ดำเนินคิวลำดับความสำคัญสองครั้งที่สิ้นสุดวันที่ มันทำได้โดยการเปลี่ยนคุณสมบัติฮีปอย่างง่าย: ต้นไม้ได้รับการกล่าวถึงว่า min-max ได้รับคำสั่งถ้าทุกองค์ประกอบในระดับที่เท่ากัน (คี่) น้อยกว่า (ดีกว่า) มากกว่าเด็กและแกรนด์เด็กทั้งหมด ระดับจะมีหมายเลขเริ่มต้นจาก 1

http://internet512.chonbuk.ac.kr/datastructure/heap/img/heap8.jpg


ยุ่งยากในการติดตั้ง แม้แต่โปรแกรมเมอร์ที่ดีที่สุดก็สามารถเข้าใจผิดได้
finnw

26

ผมชอบdatastructures แคชลบเลือน แนวคิดพื้นฐานคือการวางต้นไม้ในบล็อกที่เล็กกว่าซ้ำเพื่อให้แคชที่มีขนาดแตกต่างกันจำนวนมากจะใช้ประโยชน์จากบล็อกที่เหมาะสมกับพวกมัน สิ่งนี้นำไปสู่การใช้แคชอย่างมีประสิทธิภาพทุกอย่างตั้งแต่แคช L1 ใน RAM ไปจนถึงชิ้นข้อมูลขนาดใหญ่ที่อ่านออกจากดิสก์โดยไม่จำเป็นต้องทราบขนาดเฉพาะของชั้นแคชเหล่านั้น


การถอดความที่น่าสนใจจากลิงก์นั้น: "กุญแจสำคัญคือโครงร่างของ Van Emde Boas ซึ่งตั้งชื่อตามโครงสร้างข้อมูลของ van van Emde Boas ในปี 1977 โดย Peter van Emde Boas"
sergiol

23

ซ้ายเอนสีแดงสีดำต้นไม้ การใช้งานอย่างง่ายของต้นไม้สีแดงดำโดย Robert Sedgewick ตีพิมพ์ในปี 2551 (ประมาณครึ่งหนึ่งของรหัสที่ต้องนำไปปฏิบัติ) หากคุณเคยมีปัญหาในการพันรอบการใช้งานต้นไม้สีแดงดำอ่านเกี่ยวกับตัวแปรนี้

คล้ายกันมาก (ถ้าไม่เหมือนกัน) กับ Andersson Trees



19

Bootstrapped heter skew-binomialโดย Gerth Stølting Brodal และ Chris Okasaki:

แม้จะมีชื่อยาว แต่ก็มีการดำเนินการฮีปที่เหมาะสมที่สุดแบบ asymptotically

  • O(1)ขนาด, สหภาพ , แทรก, ขั้นต่ำ
  • O(log n) deleteMin

หมายเหตุสหภาพที่ใช้เวลาO(1)มากกว่าO(log n)เวลาที่แตกต่างจากกองอื่น ๆ ที่รู้จักกันดีที่ถูกปกคลุมทั่วไปในตำราโครงสร้างข้อมูลเช่นกองฝ่ายซ้าย และแตกต่างจากฟีโบนัชชีฮีปซิมโทติคเหล่านี้เป็นกรณีที่เลวร้ายที่สุดแทนที่จะถูกตัดจำหน่ายแม้ว่าจะใช้ไปเรื่อย ๆ

มีการนำไปใช้งานหลายอย่าง ใน Haskell

พวกเขามาจาก Brodal และ Okasaki ร่วมกันหลังจาก Brodal เกิดขึ้นกับกองที่จำเป็นด้วย asymptotics เดียวกัน


18
  • Kd-Treesโครงสร้างข้อมูลเชิงพื้นที่ที่ใช้ (ในหมู่อื่น ๆ ) ใน Real-Time Raytracing มีข้อเสียที่รูปสามเหลี่ยมที่ตัดกันตัดกันช่องว่างที่แตกต่างกันจำเป็นต้องถูกตัดออก โดยทั่วไปแล้ว BVH จะเร็วกว่าเนื่องจากมีน้ำหนักเบากว่า
  • MX-CIF Quadtreesจัดเก็บกล่องขอบเขตแทนชุดจุดโดยพลการโดยรวมควอดทรีปกติกับต้นไม้ไบนารีที่ขอบของล่าม
  • HAMTแผนที่แฮชแบบลำดับชั้นที่มีเวลาเข้าถึงซึ่งโดยทั่วไปจะเกิน O (1) แผนที่แฮชเนื่องจากค่าคงที่ที่เกี่ยวข้อง
  • Inverted Indexเป็นที่รู้จักกันดีในแวดวงเครื่องมือค้นหาเนื่องจากมันใช้สำหรับการเรียกค้นเอกสารที่เกี่ยวข้องกับคำค้นหาต่างๆอย่างรวดเร็ว

ส่วนใหญ่หากไม่ได้ทั้งหมดจะถูกบันทึกไว้ใน NIST Dictionary ของอัลกอริทึมและโครงสร้างข้อมูล


18

ต้นไม้บอล เพียงเพราะพวกเขาทำให้ผู้คนหัวเราะคิกคัก

ต้นไม้ลูกเป็นโครงสร้างข้อมูลที่ดัชนีจุดในพื้นที่ตัวชี้วัด นี่คือบทความเกี่ยวกับการสร้างพวกเขา พวกเขามักจะใช้สำหรับการค้นหาเพื่อนบ้านที่ใกล้ที่สุดเพื่อจุดหรือเร่ง k- หมายถึง


เหล่านี้เป็นที่รู้จักกันทั่วไปว่าเป็นต้นไม้ "จุดได้เปรียบ" หรือต้นไม้ vp en.wikipedia.org/wiki/Vp-tree
Edward KMETT

17

ไม่ใช่โครงสร้างข้อมูลจริงๆ วิธีการเพิ่มประสิทธิภาพของอาร์เรย์ที่จัดสรรแบบไดนามิก แต่บัฟเฟอร์ช่องว่างที่ใช้ใน Emacs นั้นยอดเยี่ยม


1
แน่นอนฉันจะพิจารณาว่าเป็นโครงสร้างข้อมูล
Christopher Barber

สำหรับทุกคนที่สนใจนี่คือสิ่งที่โมเดลเอกสาร (เช่น PlainDocument) สนับสนุนส่วนประกอบข้อความแบบสวิงได้รับการปรับใช้เช่นกัน ก่อนหน้า 1.2 ฉันเชื่อว่าแบบจำลองเอกสารเป็นอาร์เรย์แบบตรงซึ่งนำไปสู่ประสิทธิภาพการแทรกที่น่ากลัวสำหรับเอกสารขนาดใหญ่ ทันทีที่พวกเขาย้ายไปที่ Gap Buffers ทุกคนก็เหมาะสมกับโลกอีกครั้ง
Riyad Kalla

16

ต้นไม้เฟนวิค มันเป็นโครงสร้างข้อมูลเพื่อเก็บผลรวมขององค์ประกอบทั้งหมดในเวกเตอร์ระหว่างสอง subindexes i และ j ที่ได้รับ วิธีแก้ปัญหาเล็กน้อยซึ่งเป็นการคำนวณผลรวมเนื่องจากการเริ่มต้นไม่อนุญาตให้อัปเดตรายการ (คุณต้องทำงาน O (n) เพื่อติดตาม)

Fenwick Trees อนุญาตให้คุณอัปเดตและสืบค้นใน O (บันทึก n) และวิธีการทำงานนั้นยอดเยี่ยมและเรียบง่าย มันอธิบายได้ดีจริงๆในกระดาษต้นฉบับของ Fenwick มีให้ที่นี่:

http://www.cs.ubc.ca/local/reading/proceedings/spe91-95/spe/vol24/issue3/spe884.pdf

พ่อของมันต้นไม้ RQM ก็เจ๋งมาก: มันช่วยให้คุณเก็บข้อมูลเกี่ยวกับองค์ประกอบขั้นต่ำระหว่างสองดัชนีของเวกเตอร์และมันยังทำงานในการอัพเดทและแบบสอบถาม O (บันทึก n) ฉันชอบที่จะสอน RQM ก่อนแล้วจึงไปที่ต้นเฟนวิค


ฉันกลัวนี้เป็นที่ซ้ำกัน บางทีคุณต้องการเพิ่มคำตอบก่อนหน้า?
Francois G

ที่เกี่ยวข้องยังมีต้นไม้กลุ่มซึ่งมีประโยชน์สำหรับการทำแบบสอบถามทุกช่วง
dhruvbird


13

ชุดที่ซ้อนกันนั้นดีสำหรับการแสดงแผนผังในฐานข้อมูลเชิงสัมพันธ์และรันเคียวรีบนชุดเหล่านั้น ตัวอย่างเช่น ActiveRecord (Ruby on Rails 'ORM เริ่มต้นของ Rails) มาพร้อมกับชุดปลั๊กอินที่ซ้อนง่ายซึ่งทำให้การทำงานกับต้นไม้เป็นเรื่องเล็กน้อย


12

เป็นโดเมนเฉพาะที่สวย แต่โครงสร้างข้อมูลครึ่งขอบค่อนข้างเรียบร้อย มันมีวิธีการย้ำข้ามตาข่ายรูปหลายเหลี่ยม (ใบหน้าและขอบ) ซึ่งมีประโยชน์มากในคอมพิวเตอร์กราฟิกและเรขาคณิตคอมพิวเตอร์

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