Thuật toán sắp xếp không gian liên tục hiệu quả nhất là gì?


19

Tôi đang tìm kiếm một thuật toán sắp xếp cho các mảng int không phân bổ bất kỳ byte nào ngoài kích thước của mảng và bị giới hạn theo hai hướng dẫn:

  1. SWAP: hoán đổi chỉ số tiếp theo với chỉ số hiện tại;

  2. DI CHUYỂN: di chuyển con trỏ đến chỉ số +1 hoặc -1;

Đó là, bạn không thể hoán đổi các chỉ mục không lân cận, cũng không trao đổi chỉ mục 100, sau khi bạn vừa trao đổi chỉ mục 10. Thuật toán hiệu quả nhất là gì - tức là thuật toán sử dụng tổng số lần di chuyển ít hơn?


13
Không có gì lạ, đó là một cỗ máy vật lý sẽ sắp xếp một danh sách các xe được dán vào một cuộn băng dính được cuộn lại. Máy chỉ có thể di chuyển băng tiến hoặc lùi và chỉ có thể trao đổi các thẻ lân cận, của corse. Trong thế giới thực, bạn không thể dịch chuyển tức thời, vì vậy, đó là những hạn chế ...
MaiaVictor 28/03/2016

2
Vì vậy, khi bạn nói rằng bạn muốn một thuật toán không phân bổ bất kỳ byte nào ngoài kích thước của mảng , tôi đoán bạn chỉ đề cập đến lưu trữ phần tử, phải không? Tôi vẫn có thể phân bổ quầy và như vậy?
Darkhogg

5
Ồ chắc chắn rồi. Tất nhiên. Bạn có thể phân bổ một số cấu trúc bổ sung. Bạn thậm chí có thể phân bổ toàn bộ mảng và thực hiện rất nhiều tính toán thực sự nặng nề và được tính là 0 chi phí. Điều duy nhất bạn cần giảm thiểu là số lượng SWAP / DI CHUYỂN của máy vật lý thực tế, vì nó chậm. Sắp xếp bong bóng là cách tốt nhất tôi có thể nghĩ ra, nhưng tôi đoán nên có những lựa chọn tốt hơn.
MaiaVictor 28/03/2016

1
Tôi không nghĩ có một thuật toán như vậy. Nếu không có bất kỳ bộ nhớ thêm, bạn sẽ không có cách nào để lưu trữ bất kỳ nhà nước kiểm soát.
Raphael

1
@aussm: yeah, sau đó với RAM không giới hạn và khả năng sao chép băng vào RAM và tính toán tùy ý trên nó miễn phí, thuật toán "thử mọi thứ và áp dụng tốt nhất" là tối ưu về số lần di chuyển của băng. Không có khả năng thực tế, nhưng đó là vì trong thực tế thời gian chạy sẽ là hàng nghìn năm chứ không phải 0 ;-) Nếu chi phí N di chuyển để sao chép một băng có chiều dài N vào RAM, thì lực lượng vũ phu ngây thơ có thể không tối ưu nhưng nó nằm trong N tối ưu. Nhưng không có vấn đề nào cụ thể cho vấn đề của bạn: nhiều vấn đề khi được nêu theo cách này có thể được giải quyết "ngoại tuyến" bằng thuật toán không có thật.
Steve Jessop

Câu trả lời:


13

Hãy xem xét loại cocktail shaker , đây là phiên bản hai chiều của loại bong bóng. Bạn bong bóng từ thấp đến cao, và sau đó (đây là phần được thêm vào) bạn bong bóng từ cao xuống thấp, lặp lại cho đến khi hoàn thành. Đây vẫn là , nhưng nó tạo ra số đường chuyền trung bình ít hơn đáng kể, bởi vì các phần tử nhỏ gần đầu cao của mảng sẽ được chuyển đến vị trí cuối cùng của chúng trong một lần thay vì N vượt qua. Ngoài ra, bạn có thể theo dõi các vị trí thấp nhất và cao nhất nơi xảy ra hoán đổi; vượt qua sau đó không cần quét vượt quá những điểm đó.O(n2)


4

Số lượng giao dịch hoán đổi của các phần tử liền kề cần thiết để đặt hàng một mảng bằng số lượng nghịch đảo trong mảng. Với tổng số n phần tử, có nhiều nhất là nghịch đảo n * (n-1) / 2 , do đó sắp xếp bong bóng mang lại số lượng hoán đổi tối ưu không có triệu chứng trong mô hình này.


Trên thực tế, sắp xếp bong bóng sẽ cho chính xác số lần hoán đổi tối ưu. Tuy nhiên, đối với mỗi hoán vị, có một số cách để thực hiện số lần hoán đổi tối ưu và không rõ ràng cách nào làm giảm tổng số lần di chuyển. (Theo loại bong bóng, tôi có nghĩa là "chọn thứ không lớn nhất được sắp xếp và di chuyển đến cuối sắp xếp")
Peter Kravchuk

4

O(n2)

+

Thuật toán không sử dụng cờ boolean để biết liệu chúng ta có hoán đổi bất kỳ phần tử nào hay không, được đưa ra dưới đây (mẹo giữ thông tin ở trạng thái của máy, thay vì bộ nhớ):

Start:
    Do until we are not at the leftmost position (Op 4)
        move left (Op 2b)

Check:
    If we are at rightmost position (Op 3)
        goto Finished:
    If current value is larger than next value (Op 5)
        goto Unfinished:
    move right (Op 2a)
    Repeat Check:

Unfinished:
    If we are at rightmost position (Op 3)
        goto Start:
    If current value is larger than next value (Op 5)
        swap the elements (Op 1) and move right (Op 2a)
    Repeat Unfinished:

Finished:
    The list is sorted now, output it.

Giải pháp của Eric Lippert, loại gnome cũng hoạt động, bởi vì về cơ bản nó là một loại bong bóng hai chiều.


Điều gì về sắp xếp chèn?
Darkhogg

Sắp xếp bong bóng cần ít nhất hai bộ đếm vòng lặp đã nhiều hơn mức cho phép.
Raphael

1
Không, bạn có thể đi sang trái và phải, rồi từ phải sang trái, cho đến khi không có thay đổi (tức là tối đa n lần) mà không cần sử dụng bộ đếm. Bạn thậm chí không cần thêm không gian cho một cờ boolean cần lưu ý nếu có thay đổi. Nếu có một sự thay đổi, bạn chỉ cần chuyển sang một chương trình con khác cũng làm như vậy, ngoại trừ đó là một chương trình con khác.
Shreesh

1
Và tất nhiên, tôi giả sử bạn có thể đọc trống ở cả hai đầu để bạn có thể biết rằng nó đang bắt đầu hoặc kết thúc danh sách. Ngoài ra, tôi giả sử chúng ta đọc cả yếu tố hiện tại và tiếp theo để biết liệu chúng ta có cần trao đổi hay không.
Shreesh

1
Hoặc, nếu chúng tôi sửa đổi trao đổi toán tử thành "trao đổi nếu không theo thứ tự tăng dần".
Shreesh
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.