Làm thế nào để một danh sách bỏ qua hoạt động?


14

Đối với một bài tập về nhà, tôi cần hiểu làm thế nào một danh sách bỏ qua hoạt động.

Tôi đã lập trình được hơn 2 năm rồi (tôi biết điều đó không lâu trong thực tế) và tôi thậm chí chưa bao giờ nghe về một danh sách bỏ qua.

Tôi đã xem qua tất cả các hướng dẫn mà tôi có thể tìm thấy, và tôi vẫn chỉ hiểu được cách chúng hoạt động. Tôi thậm chí đã tìm kiếm Code Review để triển khai ví dụ và chỉ tìm thấy một đánh giá; và nó thậm chí không phải là một thực hiện đầy đủ. Tôi đã xem qua việc thực hiện mẫu được cung cấp bởi khóa học, và nó hoàn toàn tàn bạo. Giữa việc thiếu các phương thức thích hợp và các tên biến đơn, tôi không biết nó hoạt động như thế nào.

Làm thế nào để một danh sách bỏ qua hoạt động? Là kiến ​​thức về một danh sách bỏ qua cần thiết để hiểu các cấu trúc dữ liệu nâng cao hơn?



1
Tư vấn giáo dục rõ ràng lạc đề . Vì đây là về cấu trúc dữ liệu chứ không phải giáo dục, tôi đã chỉnh sửa câu hỏi của bạn để loại bỏ những phần đó. Tôi cũng khuyên bạn nên đọc liên kết Wikipedia mà tôi đã chỉnh sửa và cập nhật câu hỏi của bạn với các chi tiết cụ thể hơn về những gì bạn vẫn chưa hiểu.

@Snowman Cảm ơn. Tôi chỉ nói thêm rằng để ngăn chặn những bình luận như "hỏi giáo viên của bạn". Tôi sẽ ghi nhớ điều đó cho lần tới. Và bạn đã thêm một chỉnh sửa thay đổi câu hỏi. Cuối cùng, tôi không yêu cầu mọi người giải thích cách họ làm việc vì tôi cho rằng điều đó không chính đáng (mặc dù tôi sẽ không phản đối một lời giải thích tốt). Tôi chỉ muốn biết tầm quan trọng của việc học.
Carcigenicate

1
@Carcigenicate giải thích làm thế nào họ làm việc thực sự là nhiều hơn về chủ đề hơn yêu cầu nếu bạn sẽ nhìn thấy chúng trong thế giới thực. Chúng tôi chỉ có thể đoán những gì bạn sẽ làm và các lĩnh vực khác nhau. Hỏi xem chúng ta có thấy chúng trong thế giới thực đang thăm dò ý kiến ​​của chúng ta về "vâng, tôi nhìn thấy chúng và sử dụng chúng" hoặc "không, không bao giờ nghe về nó" - điều này không tạo ra câu trả lời hay hoặc hữu ích cho người khác đọc.

Câu trả lời:


29

Ngày xưa, trong lớp cấu trúc dữ liệu, chúng ta đã học được cách cây AVL hoạt động . Tôi đã có được điều đó trong một trong các lớp học của mình, nhưng người hướng dẫn nói rằng "bạn sẽ không bao giờ thực sự sử dụng thứ này" và thay vào đó chúng tôi đã học 2-3 cây và b * cây thay thế. Đó là những ngày mà bộ nhớ bị hạn chế và các quy trình được xâu chuỗi đơn lẻ. Bạn đã không sử dụng một deque khi một danh sách liên kết đơn cũng sẽ hoạt động tốt.

Danh sách bỏ qua ngày nay phổ biến hơn nhiều với bộ nhớ khả dụng hơn và đồng thời là một vấn đề (bạn không cần phải khóa nhiều khi đóng vai trò là nhà văn trong danh sách bỏ qua - so với mọi thứ với cây AVL).

Thành thật mà nói, đó là cấu trúc dữ liệu yêu thích của tôi bây giờ ở chỗ nó là thứ tôi có thể dễ dàng suy luận về cách thức hoạt động của nó bên dưới và nơi mà nó sẽ có lợi thế hoặc bất lợi khi sử dụng.

Bạn sẽ không cần phải viết một từ đầu (trừ khi bạn nhận được nó như một câu hỏi phỏng vấn - nhưng sau đó bạn có khả năng thực hiện một cây AVL).

Bạn đang đi đến cần phải hiểu lý do tại sao bạn muốn chọn một ConcurrentSkipListMaptrong Java chứ không phải là một HashMaphoặc TreeMaphoặc bất kỳ việc triển khai bản đồ khác.


Để hiểu cách thức hoạt động của nó, bạn cần hiểu cách cây nhị phân hoạt động. Chờ đã, để tôi sửa đổi điều đó. Bạn cần hiểu làm thế nào một cây nhị phân cân bằng hoạt động. Không cân bằng cây nhị phân, bạn không nhận được bất kỳ lợi thế thực sự nào với việc tra cứu nó.

Hãy nói rằng chúng ta đã có cây này:

Cây nhị phân

Và chúng tôi chèn một '8' vào nó. Bây giờ chúng tôi đã có:

Cây nhị phân không cân bằng

Và điều đó không cân bằng. Vì vậy, chúng tôi đi và làm điều kỳ diệu là cân bằng nó thông qua một số thực hiện ...

cây cân đối

Và bạn đã có một cây cân bằng một lần nữa. Nhưng đó là rất nhiều phép thuật tôi vẫy tay.

Hãy có một danh sách bỏ qua.

danh sách bỏ qua lý tưởng

Điều này xảy ra là một lý tưởng hóa. Rất ít, nhưng nó cho thấy bản chất cây nhị phân cân bằng mà lý tưởng skiplist xấp xỉ.

Bây giờ, chúng tôi muốn chèn 6 vào đó. Đây là chèn nó giống như một danh sách liên kết. Tuy nhiên, chúng tôi bắt đầu từ đầu và đi xuống. Các điểm trên đến 5. Là 6> 5? Đúng. Ok, điểm cao nhất đến cuối cùng bây giờ, vì vậy chúng tôi đi xuống ngăn xếp (chúng tôi ở trên 5). Tiếp theo là 7. Là 6> 7? Không. Vì vậy, chúng tôi đi xuống một cấp độ và chúng tôi ở cấp độ cơ sở vì vậy chúng tôi chèn 6 ở bên phải của 5.

Chúng tôi lật một đồng xu - đầu chúng tôi xây dựng, đuôi chúng tôi ở lại. Đuôi. Không cần phải làm gì thêm.

bỏ qua danh sách sau khi chèn

Bây giờ hãy chèn 8 cái đó. 8> 5? Vâng. 8> 7? Vâng. Và bây giờ chúng tôi lại ở cấp độ dưới cùng một lần nữa sau khi đi theo mũi tên và ngăn xếp xung quanh và chúng tôi kiểm tra 8> 11? Không. Vì vậy, chúng tôi chèn 8 ở bên phải của 7.

Chúng tôi lật một đồng xu - đầu chúng tôi xây dựng, đuôi chúng tôi ở lại. Đuôi. Không cần phải làm gì thêm.

bỏ qua danh sách sau khi chèn

Trong cây cân bằng, chúng ta sẽ làm việc với nhau về việc cây không được cân bằng ngay bây giờ. Nhưng đây không phải là một cái cây - đó là một danh sách bỏ qua. Chúng tôi ước chừng một cây cân bằng.

Bây giờ, hãy chèn 10. Tôi sẽ tránh tất cả các so sánh.

Chúng tôi lật một đồng xu - đầu chúng tôi xây dựng, đuôi chúng tôi ở lại. Thủ trưởng! Và lật nó lần nữa, Thủ trưởng một lần nữa! Lật nó một lần nữa, ok, có một cái đuôi. Hai cấp trên danh sách liên kết cơ sở.

bỏ qua danh sách sau khi chèn

Ưu điểm ở đây là bây giờ nếu chúng ta sẽ chèn 12, chúng ta có thể bỏ qua từ 5 đến 10 mà không cần thực hiện tất cả các so sánh khác. Chúng ta có thể bỏ qua chúng với danh sách bỏ qua. Và chúng ta không phải lo lắng về cây cân bằng - tính chất xác suất của việc xếp chồng làm điều đó cho chúng ta.

Tại sao điều này rất hữu ích? Bởi vì khi chèn 10 tôi có thể làm điều đó bằng cách khóa ghi trên con trỏ 5 và 7 và 8 chứ không phải toàn bộ cấu trúc. Và trong khi tôi đang làm điều đó, độc giả vẫn có thể xem qua danh sách bỏ qua mà không có trạng thái không nhất quán. Để sử dụng đồng thời, nó nhanh hơn không phải khóa. Để lặp lại lớp dưới cùng, nó nhanh hơn một cái cây (niềm vui của thuật toán BFS và DFS cho điều hướng cây - bạn không phải lo lắng về chúng).

Bạn sẽ gặp nó chứ? Bạn có thể sẽ thấy nó được sử dụng ở những nơi. Và sau đó bạn sẽ biết lý do tại sao tác giả chọn triển khai đó thay vì một TreeMaphoặc HashMapcho cấu trúc.

Phần lớn trong số này đã được mượn từ bài đăng trên blog của tôi: Danh sách bỏ qua


Cảm ơn bạn. Nó thậm chí không phải là việc thực hiện chung mà tôi không hiểu; Tôi nhận được sự tương đồng của họ với BST. Tôi đã cố gắng nghĩ xem làm thế nào tôi thực hiện nó và ý nghĩ quản lý tất cả các con trỏ / tài liệu tham khảo liên tục làm tôi bối rối. Có lẽ tôi đã để mình quá nản lòng. Cảm ơn. Tôi sẽ thử chọn nó vào ngày mai bằng cách sử dụng câu trả lời của bạn làm điểm bắt đầu.
Carcigenicate

2
@Carcigenicate bạn cũng có thể thấy bài báo gốc giới thiệu chúng hữu ích - Bỏ qua danh sách: Giải pháp thay thế cho cây cân bằng . Đó là một bài viết khá dễ hiểu so với hầu hết các bài báo học thuật có thể đi qua đầu người dân. Bảng 2 là lý do tại sao bạn sẽ thấy chúng được sử dụng. Đó là yếu tố thời gian để chèn hoặc xóa được thêm vào độ phức tạp của các giải pháp khác .

2
Một danh sách liên kết là "chỉ là một cây thoái hóa rất mất cân bằng". Một danh sách bỏ qua là loại thêm một phần trở lại một số loại cấu trúc cây trên đầu danh sách. Cá nhân, tôi là một fan hâm mộ lớn của các cấu trúc dữ liệu liên tục và cây dường như dễ dàng lý luận hơn trong bối cảnh cụ thể đó. Tôi không nghĩ rằng đó là một sự trùng hợp ngẫu nhiên mà Clojure, Scala, et al. dường như đang hội tụ một số loại Hash theo kiểu Bagwell như cấu trúc dữ liệu cơ bản của chúng. (Phil Bagwell thậm chí đã tham gia vào việc thiết kế lại khung bộ sưu tập của Scala cho Scala 2.8.) Mặc dù vậy, danh sách bỏ qua vẫn rất hay.
Jörg W Mittag

Đó là lời giải thích tốt nhất về cách một danh sách bỏ qua hoạt động mà tôi từng đọc.
gabious
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.