2012-05-04 25 views
5

tùy chọn của tôi là gì? Tôi cần phải gọi rất nhiều append s (đến bên phải) và popleft s (từ đầu bên trái, một cách tự nhiên), nhưng cũng phải đọc từ giữa bộ nhớ, sẽ tăng dần theo tính chất của thuật toán. Tôi muốn có tất cả các hoạt động này trong O(1).O (1) deque có thể lập chỉ mục các số nguyên trong Python

Tôi có thể thực hiện nó trong C dễ dàng đủ trên mảng được định địa chỉ tròn (từ là gì?) Sẽ tự động phát triển khi nó đầy; nhưng về Python thì sao? Con trỏ đến các ngôn ngữ khác được đánh giá cao quá (tôi nhận ra các "bộ sưu tập" thẻ là Java hơn định hướng và sẽ đánh giá cao sự so sánh, nhưng là một mục tiêu thứ cấp).

Tôi đến từ nền Lisp và rất ngạc nhiên khi biết rằng trong Python loại bỏ phần tử đầu khỏi danh sách là hoạt động O(n). deque có thể là câu trả lời ngoại trừ tài liệu cho biết quyền truy cập là O(n) ở giữa. Có gì khác, được xây dựng trước không?

+0

nói chung, http://en.wikipedia.org/wiki/Hashed_array_tree có thể có liên quan. –

Trả lời

7

Bạn có thể nhận được cấu trúc dữ liệu O (1) phân bổ bằng cách sử dụng hai danh sách python, một giữ nửa trái của deque và một còn lại giữ nửa bên phải. Nửa phía trước được lưu trữ đảo ngược nên đầu bên trái của deque nằm ở mặt sau của danh sách. Một cái gì đó như thế này:

class mydeque(object): 

    def __init__(self): 
    self.left = [] 
    self.right = [] 

    def pushleft(self, v): 
    self.left.append(v) 

    def pushright(self, v): 
    self.right.append(v) 

    def popleft(self): 
    if not self.left: 
     self.__fill_left() 
    return self.left.pop() 

    def popright(self): 
    if not self.right: 
     self.__fill_right() 
    return self.right.pop() 

    def __len__(self): 
    return len(self.left) + len(self.right) 

    def __getitem__(self, i): 
    if i >= len(self.left): 
     return self.right[i-len(self.left)] 
    else: 
     return self.left[-(i+1)] 

    def __fill_right(self): 
    x = len(self.left)//2 
    self.right.extend(self.left[0:x]) 
    self.right.reverse() 
    del self.left[0:x] 

    def __fill_left(self): 
    x = len(self.right)//2 
    self.left.extend(self.right[0:x]) 
    self.left.reverse() 
    del self.right[0:x] 

Tôi không chắc chắn 100% nếu sự tương tác giữa mã này và việc thực hiện khấu hao của danh sách của python thực sự gây ra trong thời gian O (1) cho mỗi hoạt động, nhưng ruột của tôi nói như vậy.

+0

cảm ơn rất nhiều, sẽ nghĩ về nó. sẽ 'del self.right [0: x]' lấy O (n) thời gian? và 'mở rộng' quá? –

+0

thực sự, tôi không bao giờ gọi 'popright' và' pushleft' trong thuật toán này, vì vậy tôi sẽ trao đổi quyền đảo ngược cho bên trái bất cứ khi nào bên trái bị cạn kiệt. Thật tuyệt vời! Cảm ơn rất nhiều! –

+1

Có, nhưng ý tưởng là 'fill_right' và' fill_left' chỉ được gọi là mọi hoạt động O (n) sao cho mỗi thao tác mất thời gian O (1). Tôi khá chắc chắn những gì bạn yêu cầu chỉ có thể trong thời gian O (1) khấu trừ trừ khi kích thước được giới hạn (thay đổi kích thước bạn đề cập trong Q cho một C thực hiện sẽ làm cho nó O (n) trường hợp xấu nhất quá). –

3

Truy cập vào giữa danh sách lisp cũng là O (n).

Python list s là danh sách mảng, đó là lý do tại sao popping đầu là tốn kém (popping đuôi là thời gian liên tục).

Điều bạn đang tìm kiếm là một mảng có xóa thời gian liên tục (khấu hao) ở đầu; về cơ bản có nghĩa là bạn sẽ phải xây dựng một cơ sở dữ liệu trên đầu trang của list sử dụng xóa bỏ lười biếng và có thể tái chế các vùng bị xóa do lười biếng khi hàng đợi trống.

Cách khác, sử dụng thẻ bắt đầu bằng # và một số nguyên để theo dõi phạm vi tiếp giáp hiện tại của các phím.

+0

[doc] (http://docs.python.org/genindex-H.html) không có "hashtable" trong đó. –

+0

Tôi có thể xóa một phạm vi tiếp giáp khỏi đầu danh sách trong thời gian O (n) không? Làm sao? –

+0

@WillNess Chưa hết ... các lập trình viên python vẫn sử dụng hashtables. Nếu bạn đang tìm kiếm các hashtables dưới 'H', thì tôi khuyên bạn nên làm theo một hướng dẫn (hoặc nghiên cứu kỹ tài liệu) để tìm hiểu về những gì python cung cấp. – Marcin

0

Python's Queue Module có thể giúp bạn, mặc dù tôi không chắc chắn nếu truy cập là O(1).

+0

Hàng đợi không hỗ trợ quyền truy cập vào giữa hàng đợi. – Marcin

Các vấn đề liên quan