Trường hợp xấu nhất


35

Tôi đang gặp khó khăn trong việc tìm kiếm các tài nguyên tốt đưa ra trường hợp xấu nhất trong thuật toán sắp xếp ổn định . Có ai biết bất kỳ nguồn lực tốt?O(nlnn)

Chỉ cần một lời nhắc nhở, tại chỗ có nghĩa là nó sử dụng mảng được truyền vào và thuật toán sắp xếp chỉ được phép sử dụng không gian thừa không đổi. Ổn định có nghĩa là các phần tử có cùng khóa xuất hiện theo cùng một thứ tự trong mảng được sắp xếp như chúng đã làm trong bản gốc.

Ví dụ, sắp xếp hợp nhất ngây thơ là trường hợp xấu nhất và ổn định nhưng sử dụng không gian thừa O ( n ) . Quicksort tiêu chuẩn có thể được thực hiện ổn định, tại chỗ nhưng là trường hợp xấu nhất O ( n 2 ) . Heapsort được đặt ra, trường hợp xấu nhất O ( n ln n ) nhưng không ổn định. Wikipedia có một biểu đồ đẹp trong đó các thuật toán sắp xếp có nhược điểm nào. Lưu ý rằng không có thuật toán sắp xếp nào mà chúng liệt kê có cả ba điều kiện ổn định, trường hợp xấu nhất O ( n ln nO(nlnn)O(n)O(n2)O(nlnn) và đang ở vị trí.O(nlnn)

Tôi đã tìm thấy một bài báo gọi là " Sáp nhập tại chỗ thực tế" của Katajainen, Pasanen và Teuhola, trong đó tuyên bố có trường hợp xấu nhất trong biến thể sáp nhập ổn định. Nếu tôi hiểu chính xác kết quả của họ, họ sẽ sử dụng (từ dưới lên?) Hợp nhất đệ quy trên 1 đầu tiênO(nlnn) của mảng và1sau14 của mảng và sử dụng1thứ hai12 như không gian đầu để làm hợp nhất. Tôi vẫn đang đọc qua điều này vì vậy bất kỳ thông tin nào khác về việc liệu tôi diễn giải kết quả của họ có được đánh giá cao hay không.14

Tôi cũng sẽ rất quan tâm đến trường hợp xấu nhất ở vị trí quicksort ổn định. Theo những gì tôi hiểu, việc sửa đổi quicksort thành trường hợp xấu nhất O ( n ln n ) yêu cầu chọn một trục chính phù hợp sẽ phá hủy sự ổn định mà thông thường sẽ được hưởng.O(nlnn)O(nlnn)

Đây hoàn toàn là lợi ích lý thuyết và tôi không có ứng dụng thực tế. Tôi chỉ muốn biết thuật toán có cả ba tính năng này.


Có một câu hỏi tương tự về SO ở đây với một câu trả lời đưa ra tài liệu tham khảo mà tôi đã cung cấp trong câu hỏi. Tôi tin rằng đây không phải là một câu hỏi trùng lặp vì tôi đang yêu cầu làm rõ thêm, nhiều tài liệu hơn và, với bất kỳ may mắn nào, một mô tả về thuật toán.
dùng834

1
Xem câu hỏi này trên math.stackexchange.com.
Tsuyoshi Ito

Tại sao cách chọn trục khác nhau trong QuickSort sẽ phá hủy tính ổn định của nó?
Svick

@svick, cách duy nhất tôi biết cách tạo QuickSort trong trường hợp xấu nhất là chọn trục thông minh hơn là ngẫu nhiên. Cách mà tôi học được để làm điều đó là bằng cách sử dụng thuật toán lựa chọn, sử dụng thuật toán trung bình trung bình, phá hủy sự ổn định. Nếu tôi bỏ lỡ một cái gì đó, xin vui lòng cho tôi biết. O(nlnn)
dùng834

@TsuyoshiIto, xem xét làm cho câu trả lời này. Ngoài ra, nếu bạn có thể đưa ra một bản phác thảo ngắn gọn về thuật toán, tôi nghĩ rằng nó cũng thực sự hữu ích.
dùng834

Câu trả lời:


6

Có một số thuật toán là tất cả những điều trên, và gần như tất cả chúng đã được phát minh trong 30 năm qua.

Có lẽ đẹp nhất là lớp các thuật toán được gọi là Block sort , bao gồm cả phiên bản (được gọi là WikiSort) của Kim và Kutzner vào năm 2008. Nó không chỉ ổn định và hoàn toàn tại chỗ (O (1) trên bộ nhớ trong mô hình transdichotomous), nó cũng thích ứng và do đó sẽ mất ít bước hơn để sắp xếp các danh sách gần như được sắp xếp, hội tụ đến các so sánh O (n) trong trường hợp danh sách đã được sắp xếp. Bạn có thể tìm thấy một triển khai trong C, C ++ và Java tại đây: https://github.com/BonzaiThePenguin/WikiSort

Điều đáng quan tâm là thuật toán GrailSort (cũng là một loại Block) của Huang và Langston (1989-1992), thực sự vượt trội hơn WikiSort về một số loại trường hợp thử nghiệm. Một triển khai C ++ có sẵn tại đây: https://github.com/Mrrl/GrailSort


8

Bạn có thể viết một sáp nhập tại chỗ, ổn định. Xem điều này để biết chi tiết. Theo lời của tác giả:

Một nơi đẹp - thuật toán hợp nhất. Kiểm tra nó trên các mảng đảo ngược để hiểu cách thức hoạt động của phép quay. Nhanh nhất được biết đến ở nơi ổn định sắp xếp. Không có nguy cơ nổ tung một ngăn xếp. Chi phí: một số lượng di chuyển tương đối cao. Stack vẫn có thể đắt tiền. Đây là một loại hợp nhất với một hợp nhất tại chỗ thông minh 'xoay' các mảng phụ. Mã này được sao chép từ thư viện stl C ++ và được dịch bằng Java.

Tôi sẽ không sao chép mã ở đây, nhưng bạn có thể tìm thấy nó ở liên kết hoặc bằng cách kiểm tra C ++ STL. Xin vui lòng cho tôi biết nếu bạn muốn tôi cố gắng cung cấp một mô tả chi tiết hơn về những gì đang xảy ra ở đây.


8
O(lnn)O(1)O(lnn)

Knuth cũng giải quyết vấn đề này trong TAoCP.
Raphael

O(nln2n)

1

Hãy coi đây là một nhận xét dài về một số suy nghĩ thực tế. Mặc dù đây không phải là câu trả lời cho câu hỏi của bạn, tôi nghĩ bạn có thể quan tâm đến cuộc thảo luận về Python này:

lg(N!)N1

[...]

Việc hợp nhất các đường chạy liền kề có độ dài A và B tại chỗ là rất khó khăn . Các công trình lý thuyết được biết là có thể làm được, nhưng chúng quá khó và chậm để sử dụng thực tế . Nhưng nếu chúng ta có bộ nhớ tạm thời bằng min (A, B), thật dễ dàng.

Nguồn: bug.python.org , tác giả: Tim Peters

O(nlogn)

Cũng lưu ý rằng Timsort hoạt động tốt trên các mảng đã được sắp xếp.

Vì vậy, Python sử dụng Timsort (là Mergesort với một số chỉnh sửa) và khi tôi tìm kiếm cách triển khai Java vài năm trước, đó cũng là Mergesort (tôi nghĩ giờ đây họ cũng sử dụng Timsort).

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.