2011-10-11 16 views
9

Gần đây, đối với một lớp cấu trúc dữ liệu, tôi đã được hỏi câu hỏi về việc xóa bỏ một cách lười biếng (có nghĩa là, việc xóa các mục cần xóa trước tiên, và sau đó một lúc sau đó sẽ xóa tất cả các mục được đánh dấu) thuận lợi/bất lợi cho một mảng, danh sách liên kết hoặc cây nhị phân. Dưới đây là những gì tôi đã đưa ra:Làm thế nào là xóa lười biếng thuận lợi/bất lợi cho một cây nhị phân hoặc danh sách liên kết?

  • Điều này sẽ giúp mảng vì bạn sẽ tiết kiệm thời gian để chuyển mảng mỗi khi chỉ mục bị xóa mặc dù trong thuật toán cần phải đi qua mảng, có thể không hiệu quả.
  • Điều này sẽ không giúp danh sách được liên kết vì bạn cần phải đi qua O (n) để đánh dấu một mục cần xóa.
  • Tôi không hoàn toàn chắc chắn về cây nhị phân, nhưng nếu nó là một danh sách liên kết thực hiện của một tôi sẽ tưởng tượng nó giống như danh sách liên kết?

Trả lời

2

Tôi nghĩ rằng tất cả phụ thuộc vào hoàn cảnh và yêu cầu. Trong một ý nghĩa chung bằng cách sử dụng phương pháp này, nơi chúng được đánh dấu và sau đó xóa sau đó tất cả đều có rất nhiều ưu và nhược điểm tương tự.

Các ưu điểm tương tự: -Khi được đánh dấu để xóa không có chuyển dịch của cấu trúc dữ liệu, điều này làm cho việc xóa nhanh hơn nhiều. -Bạn có thể chèn trên đầu mục đã xóa, có nghĩa là không có thay đổi cho chèn, cộng với chèn có thể được thực hiện nhanh hơn vì nó có thể ghi trên xóa đầu tiên thay vì tìm kiếm cuối danh sách

-Vị trí không gian cho mục đã xóa, vì chúng chỉ đang ngồi ở đó -Have để vượt qua hai lần để xóa một mục, một lần để đánh dấu nó và một lần nữa để xóa nó -Nhiều mục được đánh dấu để xóa sẽ làm ô nhiễm tìm kiếm cấu trúc dữ liệu mất nhiều thời gian hơn vì các mục đã xóa phải được tìm kiếm lại.

0

Có lẽ bạn cần suy nghĩ kỹ hơn về việc triển khai danh sách được liên kết. Bạn chỉ ra rằng việc xóa bỏ lười biếng sẽ KHÔNG giúp được theo bất kỳ cách nào vì thời gian tìm kiếm là tất cả thời gian cần thiết để thực hiện xóa.

Hãy suy nghĩ về những gì cần để thực sự XÓA một mục khỏi danh sách được liên kết. lưu ý: điều này giả định danh sách liên kết SINGLY (không phải danh sách liên kết kép) 1) Tìm mục cần xóa (vì đây là danh sách được liên kết SINGLE, bạn luôn phải tìm kiếm, vì bạn cần mục PREV) 2) Keep Các phần tử PREV và TIẾP THEO 3) Sửa phần tử "PREV" để trỏ đến phần tử TIẾP THEO - do đó, cách ly phần tử CURRENT 3.5) trong danh sách được liên kết kép, bạn cũng phải chăm sóc phần tử TIẾP THEO trỏ ngược lại với phần tử PREV. 4) Giải phóng bộ nhớ được liên kết với phần tử CURRENT

Bây giờ, quy trình xóa lười là gì? --- ngắn hơn nhiều 1) Tìm mục cần xóa (bạn thậm chí có thể không thực hiện tìm kiếm, vì bạn đã có con trỏ đến đối tượng bạn muốn xóa?) 2) đánh dấu mục để xóa.

*) Chờ cho "Thu gom rác" chủ đề để chạy và thực sự thực hiện các bước còn lại khi hệ thống đang "nhàn rỗi"

Một cây nhị phân thực hiện như một danh sách liên kết trong đó mỗi phần tử có một trái và một bên phải - tuy nhiên, bạn vẫn thực hiện các bước tương tự trong tìm kiếm. Tìm kiếm cây nhị phân chỉ hiệu quả hơn với O (Log (n)) tôi tin. Tuy nhiên, việc xóa từ các lệnh này trở nên phức tạp hơn vì bạn có nhiều con trỏ hơn để giải quyết (cả "TRÁI" và "QUYỀN") - vì vậy sẽ có thêm hướng dẫn để khắc phục, đặc biệt khi bạn xóa nút cây có con trỏ đến các nút cho cả hai bên trái và bên phải - một trong số chúng sẽ cần được nâng cấp lên thư mục gốc mới - tuy nhiên, điều gì sẽ xảy ra nếu chúng cũng có cả con trỏ trái và phải được gán? nút "trái/phải" gốc ở đâu? - Bạn phải cân bằng lại cây tại thời điểm này. Vì vậy, có một khoản tiết kiệm đáng kể bằng cách đánh dấu xóa từ góc nhìn của người dùng và có một bộ sưu tập rác "nhàn rỗi" để xử lý các chi tiết bộ nhớ (vì vậy người dùng không phải đợi điều đó).

0

Tôi nghĩ câu trả lời sẽ là "nó phụ thuộc" vì nhiều lý do khác nhau, nhưng tôi nghĩ bạn đang đi đúng hướng.

1) Tôi đồng ý với câu trả lời của bạn về mảng, giả sử rằng có yêu cầu không có lỗ trong mảng của bạn. Nếu bạn không bắt buộc phải thay đổi mảng xung quanh mỗi lần xóa, thì dấu mốc được đề xuất ngay bây giờ, xóa tiếp cận sau sẽ không giúp gì cả.Dù bằng cách nào, bạn đang đối phó với O (n) so với (2O (n) = O (n)) cho thuật toán, bằng nhau. Điều thực sự cần suy nghĩ là "không sắp xếp lại tất cả các thao tác xóa cùng một lúc và sắp xếp lại mỗi lần xóa riêng lẻ giúp bạn tiết kiệm bất kỳ lúc nào?" Giả sử m là số lần xóa, số lần mà mỗi phần tử sau lần xóa đầu tiên trong mảng của bạn được sắp xếp lại là O (m) cho phương pháp xóa ngay lập tức so với O (1) cho nhãn hiệu ngay bây giờ, xóa tiếp cận sau.

2) Tôi đồng ý với câu trả lời của bạn cho danh sách được liên kết.

3) Đối với cây nhị phân, tôi cho rằng nó sẽ phụ thuộc vào loại đó. Nếu bạn đang sử dụng cây nhị phân cân bằng, bạn sẽ phải cân nhắc câu hỏi tương tự như trong 1) ở trên, nhưng nếu không, suy nghĩ của bạn là chính xác và nó sẽ hoạt động giống như danh sách được liên kết.