Các cấu trúc dữ liệu ít được biết đến nhưng hữu ích là gì?


795

Có một số cấu trúc dữ liệu xung quanh thực sự hữu ích nhưng hầu hết các lập trình viên đều không biết. Đó là những ai?

Mọi người đều biết về danh sách được liên kết, cây nhị phân và giá trị băm, nhưng những gì về danh sách Bỏ quabộ lọc Bloom chẳng hạn. Tôi muốn biết thêm các cấu trúc dữ liệu không quá phổ biến, nhưng đáng để biết vì chúng dựa trên các ý tưởng tuyệt vời và làm phong phú hộp công cụ của lập trình viên.

Tái bút: Tôi cũng quan tâm đến các kỹ thuật như liên kết Dancing , sử dụng thông minh các thuộc tính của cấu trúc dữ liệu chung.

EDIT : Vui lòng bao gồm các liên kết đến các trang mô tả cấu trúc dữ liệu chi tiết hơn. Ngoài ra, hãy thử thêm một vài từ về lý do tại sao cấu trúc dữ liệu tuyệt vời (như Jonas Kölker đã chỉ ra). Ngoài ra, hãy cố gắng cung cấp một cấu trúc dữ liệu cho mỗi câu trả lời . Điều này sẽ cho phép các cấu trúc dữ liệu tốt hơn nổi lên hàng đầu chỉ dựa trên phiếu bầu của họ.


Câu trả lời:


271

Tries , còn được gọi là cây tiền tố hoặc cây crit-bit , đã tồn tại hơn 40 năm nhưng vẫn chưa được biết đến. Một cách sử dụng thử rất thú vị được mô tả trong " TRASH - Cấu trúc dữ liệu băm LC-trie động ", kết hợp một trie với hàm băm.


12
rất thường được sử dụng bởi những người kiểm tra chính tả
Steven A. Lowe

Các lần thử Burst cũng là một biến thể thú vị, trong đó bạn chỉ sử dụng tiền tố của các chuỗi làm nút và lưu trữ danh sách các chuỗi trong các nút.
Torsten Marek

Công cụ regex trong Perl 5.10 tự động tạo các lần thử.
Brad Gilbert

Theo kinh nghiệm của tôi, các thử nghiệm rất tốn kém, vì con trỏ thường dài hơn char, đó là một sự xấu hổ. Chúng chỉ phù hợp với các tập dữ liệu nhất định.
Joe

18
Vì không có câu hỏi SO nào, bất kể chủ đề nào, hoàn thành mà không có ai nhắc đến jQuery .... John Resig, người tạo ra jQuery, có một loạt cấu trúc dữ liệu thú vị của các bài đăng mà anh ấy xem xét các triển khai trie khác nhau: ejohn.org/blog/ sửa đổi-javascript-dictionary-search
Oskar Austegard

231

Bộ lọc Bloom : Mảng bit của m bit, ban đầu tất cả được đặt thành 0.

Để thêm một mục bạn chạy nó thông qua k hàm băm sẽ cung cấp cho bạn k chỉ số trong mảng mà sau đó bạn đặt thành 1.

Để kiểm tra xem một mục có trong tập hợp hay không, hãy tính các chỉ số k và kiểm tra xem tất cả chúng có được đặt thành 1 không.

Tất nhiên, điều này đưa ra một số xác suất dương tính giả (theo wikipedia, đó là khoảng 0,61 ^ (m / n) trong đó n là số lượng các mục được chèn). Âm tính giả là không thể.

Loại bỏ một mục là không thể, nhưng bạn có thể thực hiện đếm bộ lọc nở , được biểu thị bằng mảng ints và tăng / giảm.


20
Bạn quên đề cập đến việc sử dụng chúng với từ điển :) Bạn có thể ép một từ điển đầy đủ vào bộ lọc nở với khoảng 512k, giống như một hashtable không có giá trị
Chris S

8
Google trích dẫn việc sử dụng các bộ lọc Bloom trong việc triển khai BigTable.
Brian Gianforcaro

16
@FreshCode Nó thực sự cho phép bạn kiểm tra giá rẻ cho sự vắng mặt của một yếu tố trong tập hợp vì bạn có thể nhận được dương tính giả nhưng không bao giờ phủ định sai
Tom Savage

26
@FreshCode Như @Tom Savage đã nói, nó hữu ích hơn khi kiểm tra các tiêu cực. Ví dụ: bạn có thể sử dụng nó như một trình kiểm tra chính tả nhanh và nhỏ (về mặt sử dụng bộ nhớ). Thêm tất cả các từ vào đó và sau đó cố gắng tra từ mà người dùng nhập vào. Nếu bạn nhận được một phủ định, điều đó có nghĩa là nó sai chính tả. Sau đó, bạn có thể chạy một số kiểm tra đắt tiền hơn để tìm các trận đấu gần nhất và đưa ra các chỉnh sửa.
lacop

5
@ abhin4v: Bộ lọc Bloom thường được sử dụng khi hầu hết các yêu cầu có khả năng trả về câu trả lời là "không" (chẳng hạn như trường hợp ở đây), có nghĩa là có thể kiểm tra số lượng nhỏ câu trả lời "có" bằng một bài kiểm tra chính xác chậm hơn. Điều này vẫn dẫn đến việc giảm đáng kể thời gian phản hồi truy vấn trung bình . Không biết liệu Duyệt web an toàn của Chrome có làm điều đó không, nhưng đó sẽ là phỏng đoán của tôi.
j_random_hacker

140

Rope : Đây là một chuỗi cho phép trả trước giá rẻ, chuỗi con, chèn giữa và nối thêm. Tôi thực sự chỉ được sử dụng một lần, nhưng không có cấu trúc nào khác có thể sử dụng được. Các chuỗi và các khoản dự phòng mảng thông thường chỉ là quá đắt đối với những gì chúng ta cần làm và đảo ngược mọi thứ là điều không cần thiết.


Tôi đã có suy nghĩ về một cái gì đó như thế này cho mục đích sử dụng của riêng tôi. Rất vui được biết nó đã được thực hiện ở một nơi khác.
Kibbee

15
Có một triển khai trong SGI STL (1998): sgi.com/tech/stl/Rope.html
quark

2
Không biết cái gì được gọi là gần đây tôi đã viết một cái gì đó rất giống với cái này cho Java - hiệu suất rất tuyệt vời: code.google.com/p/mikeralib/source/browse/trunk/Mikera/src/
tựa


6
Liên kết của Mikera đã cũ, đây là hiện tại .
aptwebapps

128

Bỏ qua danh sách là khá gọn gàng.

Wikipedia
Danh sách bỏ qua là một cấu trúc dữ liệu xác suất, dựa trên nhiều danh sách được liên kết song song, được sắp xếp, có hiệu quả tương đương với cây tìm kiếm nhị phân (thời gian trung bình của nhật ký thứ tự cho hầu hết các hoạt động).

Chúng có thể được sử dụng thay thế cho cây cân bằng (sử dụng cân bằng cân bằng thay vì thực thi nghiêm ngặt việc cân bằng). Chúng rất dễ thực hiện và nhanh hơn nói, một cây đỏ đen. Tôi nghĩ rằng họ nên có trong mọi công cụ lập trình viên tốt.

Nếu bạn muốn có một bài giới thiệu chuyên sâu về các danh sách bỏ qua thì đây là một liên kết đến một video về bài giảng Giới thiệu về thuật toán của MIT về chúng.

Ngoài ra, đây là một applet Java thể hiện Skip Lists một cách trực quan.


+1 Qt sử dụng danh sách bỏ qua thay vì cây RB cho các bộ & bản đồ được sắp xếp của nó. Đúng, dù sao họ cũng rất tiện lợi (bằng ngôn ngữ bắt buộc).
Michael Ekstrand

2
Redis sử dụng danh sách bỏ qua để thực hiện "Bộ sắp xếp".
antirez

Danh sách bỏ qua có lẽ là cấu trúc dữ liệu yêu thích của tôi để sử dụng khi tôi cần cấu trúc dữ liệu tốt và tôi không đảm bảo về thứ tự của dữ liệu và tôi muốn triển khai đơn giản hơn các cấu trúc dữ liệu "cân bằng" khác. Thật là một điều tốt.
Earino

Lưu ý phụ thú vị: Nếu bạn thêm đủ cấp độ vào danh sách bỏ qua của mình, về cơ bản bạn sẽ kết thúc bằng cây B.
Riyad Kalla

92

Không gian chỉ số , đặc biệt là R-câyKD-cây , lưu trữ dữ liệu không gian một cách hiệu quả. Chúng tốt cho dữ liệu tọa độ bản đồ địa lý và thuật toán vị trí và tuyến đường VLSI, và đôi khi cho tìm kiếm hàng xóm gần nhất.

Mảng bit lưu trữ các bit riêng lẻ một cách gọn gàng và cho phép các hoạt động bit nhanh.


6
Các chỉ số không gian cũng hữu ích cho các mô phỏng cơ thể N liên quan đến các lực tầm xa như trọng lực.
Justin Peel

87

Khóa kéo - dẫn xuất của các cấu trúc dữ liệu sửa đổi cấu trúc để có một khái niệm tự nhiên về 'con trỏ' - vị trí hiện tại. Chúng thực sự hữu ích vì chúng đảm bảo các chỉ báo không thể nằm ngoài giới hạn - được sử dụng, ví dụ như trong trình quản lý cửa sổ xmonad để theo dõi cửa sổ nào đã tập trung.

Thật ngạc nhiên, bạn có thể lấy được chúng bằng cách áp dụng các kỹ thuật từ tính toán đến loại cấu trúc dữ liệu gốc!


2
Điều này chỉ hữu ích trong lập trình chức năng (trong các ngôn ngữ bắt buộc, bạn chỉ cần giữ một con trỏ hoặc một chỉ mục). Ngoài ra, tôi vẫn không hiểu làm thế nào Zippers thực sự hoạt động.
Stefan Monov

4
@Stefan quan điểm là bạn không cần phải giữ một chỉ mục hoặc con trỏ riêng bây giờ.
Don Stewart

69

Ở đây có một ít:

  • Suffix cố gắng. Hữu ích cho hầu hết các loại tìm kiếm chuỗi (http://en.wikipedia.org/wiki/Suffix_trie#Feftality ). Xem thêm mảng hậu tố; Chúng không hoàn toàn nhanh như cây hậu tố, nhưng nhỏ hơn rất nhiều.

  • Cây Splay (như đã đề cập ở trên). Lý do họ mát mẻ là ba lần:

    • Chúng rất nhỏ: bạn chỉ cần các con trỏ trái và phải như bạn làm trong bất kỳ cây nhị phân nào (không cần lưu trữ thông tin về màu sắc hoặc kích thước nút)
    • Chúng (tương đối) rất dễ thực hiện
    • Họ cung cấp độ phức tạp khấu hao tối ưu cho toàn bộ "tiêu chí đo lường" (thời gian tra cứu log n là thời gian mọi người đều biết). Xemhttp://en.wikipedia.org/wiki/Splay_tree#Performance_theorems
  • Cây tìm kiếm theo thứ tự heap: bạn lưu trữ một loạt các cặp (khóa, nguyên mẫu) trong một cây, sao cho đó là cây tìm kiếm liên quan đến các khóa và được sắp xếp theo đống theo các ưu tiên. Người ta có thể chỉ ra rằng một cái cây như vậy có hình dạng độc đáo (và nó không phải lúc nào cũng được đóng gói đầy đủ từ trái sang phải). Với các ưu tiên ngẫu nhiên, nó cung cấp cho bạn thời gian tìm kiếm O (log n) dự kiến, IIRC.

  • Một danh sách thích hợp là danh sách kề cho các đồ thị phẳng không được định hướng với các truy vấn lân cận O (1). Đây không phải là một cấu trúc dữ liệu như một cách cụ thể để tổ chức một cấu trúc dữ liệu hiện có. Dưới đây là cách bạn thực hiện: mọi đồ thị phẳng đều có một nút có độ lớn nhất là 6. Chọn một nút như vậy, đặt hàng xóm của nó vào danh sách lân cận, xóa nó khỏi biểu đồ và lặp lại cho đến khi đồ thị trống. Khi được cung cấp một cặp (u, v), hãy tìm u trong danh sách hàng xóm của v và cho v trong danh sách hàng xóm của u. Cả hai đều có kích thước tối đa là 6, vì vậy đây là O (1).

Theo thuật toán trên, nếu u và v là hàng xóm, bạn sẽ không có cả u trong danh sách của v và v trong danh sách của bạn. Nếu bạn cần điều này, chỉ cần thêm hàng xóm bị thiếu của mỗi nút vào danh sách hàng xóm của nút đó, nhưng lưu trữ bao nhiêu danh sách hàng xóm bạn cần xem qua để tra cứu nhanh.


Cây tìm kiếm theo thứ tự Heap được gọi là một treap. Một mẹo bạn có thể làm với những điều này là thay đổi mức độ ưu tiên của một nút để đẩy nó xuống dưới cùng của cây, nơi dễ xóa hơn.
paperhorse

1
"Cây tìm kiếm theo thứ tự Heap được gọi là một treap." - Trong định nghĩa tôi đã nghe, IIRC, một treap là cây tìm kiếm theo thứ tự heap với các ưu tiên ngẫu nhiên . Bạn có thể chọn các ưu tiên khác, tùy thuộc vào ứng dụng ...
Jonas Kölker

2
Một hậu tố trie gần như nhưng không hoàn toàn giống với cây hậu tố mát hơn nhiều , có các chuỗi và không phải các chữ cái riêng lẻ trên các cạnh của nó và có thể được xây dựng trong thời gian tuyến tính (!). Ngoài ra, mặc dù chậm hơn về mặt tiệm cận, nhưng trong thực tế, mảng hậu tố thường nhanh hơn nhiều so với cây hậu tố cho nhiều tác vụ vì kích thước nhỏ hơn và ít chỉ dẫn con trỏ hơn. Yêu đồ thị phẳng O (1) tra cứu BTW!
j_random_hacker

@j_random_hacker: mảng hậu tố không chậm hơn về mặt triệu chứng. Dưới đây là ~ 50 dòng mã để xây dựng mảng hậu tố tuyến tính: cs.helsinki.fi/u/tpkarkka/publications/icalp03.pdf
Edward KMett

1
@Edward Kmett: Thực tế tôi đã đọc bài báo đó, nó thực sự là một bước đột phá trong xây dựng mảng hậu tố . (Mặc dù người ta đã biết rằng có thể xây dựng thời gian tuyến tính bằng cách đi "qua" cây hậu tố, đây là thuật toán "trực tiếp" thực tế không thể chối cãi đầu tiên.) Nhưng một số thao tác bên ngoài xây dựng vẫn chậm hơn một cách bất thường trên mảng hậu tố trừ khi LCA bảng cũng được xây dựng. Điều đó cũng có thể được thực hiện trong O (n), nhưng bạn mất kích thước và lợi ích cục bộ của mảng hậu tố thuần túy bằng cách làm như vậy.
j_random_hacker

65

Tôi nghĩ rằng các lựa chọn thay thế không khóa cho các cấu trúc dữ liệu tiêu chuẩn, tức là hàng đợi không khóa, ngăn xếp và danh sách bị bỏ qua nhiều.
Chúng ngày càng có liên quan khi đồng thời trở thành ưu tiên cao hơn và là mục tiêu đáng ngưỡng mộ hơn nhiều so với sử dụng Mutexes hoặc khóa để xử lý đọc / ghi đồng thời.

Đây là một số liên kết
http://www.cl.cam.ac.uk/research/srg/netos/lock-free/
http://www.research.ibm.com/people/m/michael/podc-1996.pdf [Liên kết tới PDF]
http://www.boyet.com/Articles/LockfreeStack.html

Blog của Mike Acton (thường mang tính khiêu khích) có một số bài viết xuất sắc về thiết kế và phương pháp tiếp cận không khóa


Các lựa chọn thay thế không khóa rất quan trọng trong thế giới nghiện đa nhân, rất song song, có khả năng mở rộng ngày nay :-)
Earino

Vâng, một người gây rối thực sự là một công việc tốt hơn trong hầu hết các trường hợp.
deadalnix

55

Tôi nghĩ rằng Disjoint Set khá tiện lợi cho các trường hợp khi bạn cần chia một loạt các mục thành các bộ riêng biệt và thành viên truy vấn. Việc triển khai tốt các hoạt động của Liên minh và Tìm kiếm dẫn đến chi phí khấu hao không đổi một cách hiệu quả (nghịch đảo với Chức năng của Ackermnan, nếu tôi nhớ lại chính xác lớp cấu trúc dữ liệu của mình).


8
Điều này cũng được gọi là "cấu trúc dữ liệu tìm liên minh." Tôi đã rất kinh ngạc khi lần đầu tiên biết về cấu trúc dữ liệu thông minh này trong lớp thuật toán ...
BlueRaja - Danny Pflughoeft

tiện ích mở rộng union-find-xóa cũng cho phép xóa liên tục.
Cốc

4
Tôi đã sử dụng Bộ Disjoint cho máy phát Dungeon của mình, để đảm bảo tất cả các phòng đều có thể tiếp cận được bằng lối đi :)
yellowratio

52

Các đống Fibonacci

Chúng được sử dụng trong một số thuật toán được biết đến nhanh nhất (không có triệu chứng) cho rất nhiều vấn đề liên quan đến đồ thị, chẳng hạn như vấn đề Đường dẫn ngắn nhất. Thuật toán của Dijkstra chạy trong thời gian O (E log V) với các đống nhị phân tiêu chuẩn; việc sử dụng các đống Fibonacci cải thiện điều đó thành O (E + V log V), đây là một tốc độ rất lớn cho các biểu đồ dày đặc. Thật không may, mặc dù, chúng có một yếu tố liên tục cao, thường làm cho chúng không thực tế trong thực tế.


Yếu tố liên tục cao như bạn đã nói, và khó thực hiện tốt theo một người bạn đã phải. Fianally không phải là mát mẻ, nhưng vẫn, có thể đáng để biết.
p4bl0

Những kẻ này ở đây đã khiến chúng chạy cạnh tranh so với các loại heap khác: cphstl.dk/Pftimeation/SEA2010/SEA-10.pdf Có một cấu trúc dữ liệu liên quan được gọi là Ghép cặp Heaps dễ thực hiện hơn và cung cấp hiệu suất thực tế khá tốt. Tuy nhiên, phân tích lý thuyết là một phần mở.
Manuel

Từ kinh nghiệm của tôi với các đống Fibonacci, tôi phát hiện ra rằng hoạt động tốn kém của việc phân bổ bộ nhớ làm cho nó kém hiệu quả hơn một đống nhị phân đơn giản được phụ trợ bởi một mảng.
vui nhộn

44

Bất cứ ai có kinh nghiệm về kết xuất 3D nên làm quen với cây BSP . Nói chung, đó là phương pháp bằng cách cấu trúc cảnh 3D để có thể quản lý để hiển thị khi biết tọa độ và ổ trục của máy ảnh.

Phân vùng không gian nhị phân (BSP) là một phương pháp để phân chia đệ quy một không gian thành các tập lồi bằng siêu phẳng. Phân mục này làm phát sinh cảnh đại diện bằng cấu trúc dữ liệu cây được gọi là cây BSP.

Nói cách khác, đó là một phương pháp phá vỡ các đa giác có hình dạng phức tạp thành các tập lồi hoặc các đa giác nhỏ hơn bao gồm hoàn toàn các góc không phản xạ (các góc nhỏ hơn 180 °). Để biết mô tả chung hơn về phân vùng không gian, hãy xem phân vùng không gian.

Ban đầu, phương pháp này được đề xuất trong đồ họa máy tính 3D để tăng hiệu quả kết xuất. Một số ứng dụng khác bao gồm thực hiện các thao tác hình học với hình dạng (hình học rắn xây dựng) trong CAD, phát hiện va chạm trong robot và trò chơi máy tính 3D và các ứng dụng máy tính khác liên quan đến xử lý các cảnh không gian phức tạp.


... và các octrees và kd-cây có liên quan.
Lloeki

43

Cây Huffman - được sử dụng để nén.


Mặc dù nó rất thú vị, nhưng đây không phải là một loại 'Giới thiệu về thuật toán', đây là một chủ đề thuộc loại tham lam-algo?
rshepherd

38

Hãy xem Cây ngón tay , đặc biệt nếu bạn là người hâm mộ cấu trúc dữ liệu chức năng thuần túy được đề cập trước đó . Chúng là một biểu diễn chức năng của các chuỗi liên tục hỗ trợ truy cập vào các đầu trong thời gian không đổi được khấu hao, và nối và tách theo logarit thời gian theo kích thước của mảnh nhỏ hơn.

Theo bài viết gốc :

Cây 2-3 ngón tay chức năng của chúng tôi là một ví dụ của một kỹ thuật thiết kế chung được tạo ra bởi Okasaki (1998), được gọi là làm chậm đệ quy ngầm . Chúng tôi đã lưu ý rằng những cây này là một phần mở rộng của cấu trúc deque ngầm của anh ấy, thay thế các cặp bằng 2-3 nút để cung cấp sự linh hoạt cần thiết cho việc ghép và tách hiệu quả.

Cây ngón tay có thể được tham số hóa bằng một hình đơn sắc và sử dụng các hình đơn sắc khác nhau sẽ dẫn đến các hành vi khác nhau cho cây. Điều này cho phép Finger Plants mô phỏng các cấu trúc dữ liệu khác.



Hãy xem câu trả lời trùng lặp này , nó cũng đáng đọc!
Francois G

34

Bộ đệm tròn hoặc vòng - được sử dụng để phát trực tuyến, trong số những thứ khác.


4
Ngoài ra, thật kinh tởm, bằng cách nào đó quản lý để được cấp bằng sáng chế (ít nhất là khi được sử dụng cho video). ip.com/patent/USRE36801
David

Dựa trên việc đọc liên kết, tôi không nghĩ rằng cấu trúc dữ liệu được cấp bằng sáng chế, nhưng một số phát minh dựa trên nó. Tôi đồng ý rằng đây chắc chắn là một cấu trúc dữ liệu rất ít được sử dụng.
Trọng lực

33

Tôi ngạc nhiên không ai nhắc đến cây Merkle (tức là cây Hash ).

Được sử dụng trong nhiều trường hợp (chương trình P2P, chữ ký số) trong đó bạn muốn xác minh hàm băm của toàn bộ tệp khi bạn chỉ có một phần tệp có sẵn cho bạn.


32

<zvrba> Cây Van Emde-Boas

Tôi nghĩ sẽ hữu ích khi biết lý do tại sao chúng mát mẻ. Nói chung, câu hỏi "tại sao" là quan trọng nhất để hỏi;)

Câu trả lời của tôi là họ cung cấp cho bạn từ điển O (log log n) với các khóa {1..n}, không phụ thuộc vào số lượng khóa được sử dụng. Giống như việc chia đôi lặp đi lặp lại mang lại cho bạn O (log n), sqrting lặp lại mang lại cho bạn O (log log n), đó là những gì xảy ra trong cây vEB.


Họ là tốt đẹp từ quan điểm lý thuyết. Tuy nhiên, trên thực tế, thật khó để có được hiệu suất cạnh tranh từ chúng. Bài báo mà tôi biết đã khiến chúng hoạt động tốt lên tới 32 phím ( citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.2.7403 ) nhưng cách tiếp cận sẽ không mở rộng đến hơn 34-35 bit hoặc vì vậy và không có thực hiện điều đó.
Manuel

Một lý do khác khiến chúng mát mẻ là chúng là một khối xây dựng chính cho một số thuật toán lãng quên bộ nhớ cache.
Edward KMett


29

Một biến thể thú vị của bảng băm có tên là Cuckoo Hashing . Nó sử dụng nhiều hàm băm thay vì chỉ 1 để xử lý các va chạm băm. Xung đột được giải quyết bằng cách xóa đối tượng cũ khỏi vị trí được chỉ định bởi hàm băm chính và di chuyển nó đến vị trí được chỉ định bởi hàm băm thay thế. Cuckoo Hashing cho phép sử dụng không gian bộ nhớ hiệu quả hơn vì bạn có thể tăng hệ số tải lên tới 91% chỉ với 3 hàm băm mà vẫn có thời gian truy cập tốt.


5
Kiểm tra băm hopscotch tuyên bố là nhanh hơn.
chmike

27

Một đống min-max là một biến thể của một đống mà thực hiện một hàng đợi ưu tiên đúp kết thúc. Nó đạt được điều này bằng một thay đổi đơn giản đối với thuộc tính heap: Một cây được gọi là cực tiểu theo thứ tự nếu mọi phần tử ở mức chẵn (lẻ) đều nhỏ hơn (lớn hơn) so với tất cả trẻ em và cháu lớn. Các cấp được đánh số bắt đầu từ 1.

http://iNET512.chonbuk.ac.kr/dat Hạ cơ / heap / img / heap8.jpg


Lừa để thực hiện. Ngay cả những lập trình viên giỏi nhất cũng có thể hiểu sai.
Finnw

26

Tôi thích các cơ sở dữ liệu lãng quên Cache . Ý tưởng cơ bản là bố trí một cây trong các khối nhỏ đệ quy để các bộ đệm có nhiều kích cỡ khác nhau sẽ tận dụng các khối phù hợp với chúng. Điều này dẫn đến việc sử dụng hiệu quả bộ nhớ đệm ở mọi thứ, từ bộ đệm L1 trong RAM đến khối dữ liệu lớn được đọc trên đĩa mà không cần biết chi tiết cụ thể về kích thước của bất kỳ lớp bộ đệm nào.


Phiên âm thú vị từ liên kết đó: "Điều quan trọng là cách bố trí van Emde Boas, được đặt tên theo cấu trúc dữ liệu cây van Emde Boas được hình thành vào năm 1977 bởi Peter van Emde Boas"
sergiol

23

Còn lại nghiêng cây đỏ-đen . Một triển khai đơn giản hóa đáng kể các cây đỏ đen của Robert Sedgewick xuất bản năm 2008 (~ một nửa dòng mã để thực hiện). Nếu bạn đã từng gặp khó khăn trong việc thực hiện một cây Đỏ-Đen, hãy đọc về biến thể này.

Rất giống (nếu không giống hệt) với cây Andersson.



19

Những đống xiên nhị phân được khởi động bởi Gerth Stølting Brodal và Chris Okasaki:

Mặc dù tên dài của họ, họ cung cấp các hoạt động heap tối ưu không có triệu chứng, ngay cả trong một thiết lập chức năng.

  • O(1)kích thước, liên minh , chèn, tối thiểu
  • O(log n) xóaMin

Lưu ý rằng liên minh mất O(1)nhiều O(log n)thời gian hơn là không giống như các đống nổi tiếng thường được bao phủ trong sách giáo khoa cấu trúc dữ liệu, chẳng hạn như các đống bên trái . Và không giống như các đống Fibonacci , những tiệm cận đó là trường hợp xấu nhất, thay vì khấu hao, ngay cả khi được sử dụng liên tục!

nhiều triển khai trong Haskell.

Chúng được Brodal và Okasaki cùng xuất phát, sau khi Brodal nghĩ ra một đống bắt buộc với cùng một triệu chứng.


18
  • Cây Kd , cấu trúc dữ liệu không gian được sử dụng (trong số những thứ khác) trong Raytracing thời gian thực, có nhược điểm là các hình tam giác cắt nhau giao nhau giữa các không gian khác nhau cần được cắt bớt. Nói chung, BVH nhanh hơn vì nhẹ hơn.
  • Tứ giác MX-CIF , lưu trữ các hộp giới hạn thay vì các tập hợp điểm tùy ý bằng cách kết hợp một hình tứ giác thông thường với một cây nhị phân trên các cạnh của hình tứ giác.
  • HAMT , bản đồ băm phân cấp với thời gian truy cập thường vượt quá bản đồ băm O (1) do các hằng số liên quan.
  • Chỉ số đảo ngược , khá nổi tiếng trong giới công cụ tìm kiếm, bởi vì nó được sử dụng để truy xuất nhanh các tài liệu liên quan đến các cụm từ tìm kiếm khác nhau.

Hầu hết, nếu không phải tất cả, những điều này được ghi lại trên Từ điển thuật toán và cấu trúc dữ liệu của NIST


18

Cây bóng. Chỉ vì họ làm mọi người cười khúc khích.

Cây bóng là một cấu trúc dữ liệu lập chỉ mục các điểm trong một không gian số liệu. Đây là một bài viết về xây dựng chúng. Chúng thường được sử dụng để tìm hàng xóm gần nhất đến một điểm hoặc tăng tốc phương tiện k.


Đây cũng thường được gọi là cây "điểm thuận lợi" hoặc cây vp. vi.wikipedia.org/wiki/Vp-tree
Edward KMett

17

Không thực sự là một cấu trúc dữ liệu; nhiều hơn một cách để tối ưu hóa các mảng được phân bổ động, nhưng bộ đệm khoảng cách được sử dụng trong Emacs là loại tuyệt vời.


1
Tôi chắc chắn sẽ coi đó là một cấu trúc dữ liệu.
Christopher Thợ cắt tóc

Đối với bất kỳ ai quan tâm, đây chính xác là cách các mô hình Tài liệu (ví dụ PlainDocument) sao lưu các thành phần văn bản Swing cũng được triển khai; trước 1,2 tôi tin rằng các mô hình tài liệu là Mảng thẳng, dẫn đến hiệu suất chèn khủng khiếp cho các tài liệu lớn; Ngay khi họ chuyển đến Gap Buffers, tất cả đã đúng với thế giới một lần nữa.
Riyad Kalla

16

Cây Fenwick. Đây là một cấu trúc dữ liệu để giữ tổng số của tất cả các phần tử trong một vectơ, giữa hai phần tử con i và j đã cho. Giải pháp tầm thường, tính toán trước tổng số kể từ khi bắt đầu không cho phép cập nhật một mục (bạn phải làm O (n) để theo kịp).

Cây Fenwick cho phép bạn cập nhật và truy vấn trong O (log n), và cách nó hoạt động thực sự rất hay và đơn giản. Nó thực sự được giải thích rất rõ trong bài báo gốc của Fenwick, có sẵn miễn phí tại đây:

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

Cha đẻ của nó, cây RQM cũng rất tuyệt: Nó cho phép bạn giữ thông tin về phần tử tối thiểu giữa hai chỉ mục của vectơ và nó cũng hoạt động trong cập nhật và truy vấn O (log n). Tôi thích dạy RQM trước và sau đó là Cây Fenwick.


Tôi sợ đây là một bản sao . Có lẽ bạn muốn thêm vào câu trả lời trước?
Francois G

Cũng liên quan là Cây phân đoạn, rất hữu ích để thực hiện tất cả các loại truy vấn phạm vi.
dhruvbird


13

Các bộ lồng nhau rất tốt để biểu diễn các cây trong cơ sở dữ liệu quan hệ và chạy các truy vấn trên chúng. Chẳng hạn, ActiveRecord (ORM mặc định của Ruby on Rails) đi kèm với một bộ plugin lồng nhau rất đơn giản , giúp làm việc với cây tầm thường.


12

Nó khá đặc trưng cho miền, nhưng cấu trúc dữ liệu nửa cạnh khá gọn gàng. Nó cung cấp một cách để lặp lại trên các lưới đa giác (các mặt các cạnh) rất hữu ích trong đồ họa máy tính và hình học tính toán.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.