Những lớp cấu trúc dữ liệu có thể được thực hiện liên tục?


19

Cấu trúc dữ liệu liên tục là cấu trúc dữ liệu bất biến. Các thao tác trên chúng trả về một "bản sao" mới của cấu trúc dữ liệu, nhưng bị thay đổi bởi thao tác; cấu trúc dữ liệu cũ vẫn không thay đổi. Hiệu quả thường được thực hiện bằng cách chia sẻ một số dữ liệu cơ bản và tránh sao chép toàn bộ cấu trúc dữ liệu.

Câu hỏi:

  • Có kết quả nào về các lớp cấu trúc dữ liệu có thể được thực hiện liên tục (trong khi vẫn giữ các độ phức tạp giống nhau hoặc rất giống nhau) không?

  • Có thể tất cả các cấu trúc dữ liệu được thực hiện liên tục (trong khi vẫn giữ sự phức tạp giống hoặc tương tự)?

  • Có bất kỳ cấu trúc dữ liệu nào được biết là không thể được thực hiện liên tục (trong khi vẫn giữ các độ phức tạp giống nhau hoặc rất giống nhau) không?


1
Bạn không thể tạo một vectơ liên tục với độ phức tạp O (1) được bảo toàn để truy cập một phần tử ngẫu nhiên.
smossen


2
@smossen bạn có thể chứng minh điều đó?
Realz Slaw

1
Câu hỏi đầu tiên của bạn là một câu hỏi rất rộng. Có nhiều kết quả về chủ đề cấu trúc dữ liệu có thể được thực hiện liên tục. Người ta có thể viết toàn bộ cuốn sách về chủ đề này và một số người có: ví dụ, cuốn sách của Okasaki là một tác phẩm kinh điển về chủ đề này. Bạn đã thực hiện một số nghiên cứu về chủ đề này? Bạn có thể thu hẹp câu hỏi? Vì nó đứng, tôi nghi ngờ nó có thể quá rộng để phù hợp với trang web này. Có thể tách ra câu hỏi thứ 3 cho một câu hỏi riêng biệt?
DW

@Realz Slaw: Tôi không thể chứng minh chính thức, nhưng tôi nghĩ đó là lẽ thường. Truy cập O (1) vào các phần tử trong vectơ (bao gồm cả bảng băm) phụ thuộc vào thời gian cố định để giải mã địa chỉ trên một phần cứng nhất định. Sự kiên trì thêm một hoặc hai chiều ngoài chỉ số vectơ. Nhưng địa chỉ phần cứng vẫn là một chiều.
smossen

Câu trả lời:


22

Kết quả tích cực: kiên trì không tốn quá nhiều. Người ta có thể chỉ ra rằng mọi cấu trúc dữ liệu có thể được thực hiện hoàn toàn bền bỉ với tối đa độ chậm .O(lgn)

Bằng chứng: Bạn có thể lấy một mảng và làm cho nó bền bỉ bằng cách sử dụng các cấu trúc dữ liệu tiêu chuẩn (ví dụ: cây nhị phân cân bằng; xem phần cuối của câu trả lời này để biết thêm chi tiết). Điều này phát sinh sự chậm lại : mỗi lần truy cập mảng mất thời gian O ( lg n ) với cấu trúc dữ liệu liên tục, thay vì thời gian O ( 1 ) cho mảng không liên tục. Bây giờ lấy bất kỳ thuật toán bắt buộc nào có thời gian chạy trong mô hình RAM là O ( f ( n ) ) , trong đó n biểu thị lượng bộ nhớ được sử dụng. Đại diện cho tất cả bộ nhớ là một mảng lớn (vớiO(lgn)O(lgn)O(1)O(f(n))n phần tử) và làm cho nó bền bỉ bằng cách sử dụng bản đồ liên tục. Mỗi bước của thuật toán bắt buộc phải chịu nhiều nhất là làmchậm O ( lg n ) , do đó tổng thời gian chạy là O ( f ( n ) lg n ) .nO(lgn)O(f(n)lgn)

Rõ ràng có thể làm tốt hơn một chút: rõ ràng người ta có thể giảm hệ số làm chậm xuống (dự kiến, thời gian khấu hao), sử dụng các kỹ thuật trong bài báo Demaine được trích dẫn bên dưới - nhưng tôi không quen với các chi tiết của công việc đó, vì vậy tôi không thể tự bảo đảm điều này. Cảm ơn jbapple cho quan sát này.O(lglgn)


Kết quả tiêu cực: bạn không thể tránh một số chậm, đối với một số cấu trúc dữ liệu. Để trả lời câu hỏi thứ ba của bạn, tồn tại các cấu trúc dữ liệu nơi được biết là làm cho chúng bền bỉ giới thiệu một số chậm.

nO(1)O(1)Ω(lglgn)

Giới hạn dưới được quy cho Mihai Patrascu, nhưng không có trích dẫn nào cho một nguồn cung cấp các chi tiết về bằng chứng của giới hạn dưới được khẳng định này.


O(1)

Ngoài ra còn có một kết nối mạnh mẽ với các ngôn ngữ lập trình chức năng. Cụ thể, mọi cấu trúc dữ liệu có thể được thực hiện theo cách hoàn toàn chức năng (không có đột biến) đã là cấu trúc dữ liệu bền vững. (Chuyện ngược lại không nhất thiết phải như vậy, than ôi.) Nếu bạn muốn nheo mắt, bạn có thể coi đây là một định lý phân loại một phần yếu: nếu nó có thể thực hiện được bằng ngôn ngữ lập trình chức năng thuần túy với cùng giới hạn như trong một ngôn ngữ bắt buộc, sau đó có một cấu trúc dữ liệu liên tục với giới hạn cùng thời gian với ngôn ngữ không liên tục. Tôi nhận ra đây có lẽ không phải là thứ bạn đang tìm kiếm - nó chủ yếu chỉ là một sự tái hiện tầm thường của tình huống.


O(lgn)

dd

nO(lgn)O(lgn)O(lgn)

Bạn có thể tìm thấy nhiều lời giải thích hơn, với những bức ảnh đẹp, tại các tài nguyên sau:

Điều đó sẽ cho bạn ý chính. Có nhiều chi tiết cần quan tâm, nhưng các chi tiết nằm ngoài phạm vi của câu hỏi này. May mắn thay, đây là tất cả các công cụ tiêu chuẩn và có rất nhiều thông tin có sẵn trong tài liệu về cách xây dựng các cấu trúc dữ liệu đó. Vui lòng đặt câu hỏi riêng nếu các tài nguyên trên không đủ và bạn muốn biết thêm thông tin về các chi tiết xây dựng cấu trúc dữ liệu mảng liên tục.


Tôi thực sự không hiểu đoạn đầu tiên, làm thế nào tôi có thể tạo ra một mảng liên tục bằng cách sử dụng cây đỏ đen?
G. Bạch

@ G.Bach, có một lời giải thích khá hay trong các phần có nhãn "Cây tìm kiếm nhị phân" và "Cấu trúc truy cập ngẫu nhiên" (cụ thể là phương pháp cây) tại toves.org/books/persist/index.html . Để biết một mô tả hay khác, hãy xem netcode.ru/dotnet/?artID=6592#BinaryTrees và một số phần tiếp theo. Điều đó sẽ cho bạn ý chính. Các chi tiết nằm ngoài phạm vi của câu hỏi này, nhưng đây là tất cả những thứ tiêu chuẩn; Tôi khuyến khích bạn đặt một câu hỏi riêng nếu bạn muốn biết thêm thông tin về cách xây dựng cấu trúc dữ liệu như vậy.
DW

4
O(lglgn)
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.