Sắp xếp mảng 5 số nguyên với tối đa 7 so sánh


19

Làm cách nào tôi có thể sắp xếp danh sách 5 số nguyên sao cho trong trường hợp xấu nhất phải mất 7 so sánh? Tôi không quan tâm đến việc có bao nhiêu hoạt động khác được thực hiện. Tôi không biết gì đặc biệt về các số nguyên.

Tôi đã thử một vài cách tiếp cận khác nhau và chinh phục giúp tôi giảm xuống 8 so sánh, chẳng hạn như theo cách tiếp cận sáp nhập hoặc kết hợp sáp nhập với sử dụng tìm kiếm nhị phân để tìm vị trí chèn, nhưng mỗi lần tôi kết thúc với 8 so sánh trường hợp xấu nhất .

Ngay bây giờ tôi chỉ tìm kiếm một gợi ý, không phải là một giải pháp.


Bạn đã thử viết cây "so sánh" chưa? Nó có 5!=120 lá, mỗi lá tương ứng với một hoán vị của các số nguyên. Nếu bạn không biết ý của tôi về cây "so sánh với", bạn có biết bằng chứng rằng bạn cần nlogn so sánh không? Ps, điều gì khiến bạn nghĩ nó có thể?
Pål GD

1
Chà, trong phần bổ sung 8 bit hai, if(x > y)giống như if((x - y) & 0x80)phần khó so sánh. Tôi đoán chúng ta nên quên rằng các đối tượng là số nguyên và giả sử chúng ta phải sử dụng một số compare(x, y)chức năng ma thuật để so sánh các đối tượng đó ...
Karolis Juodelė

2
Liệu 'hãy xem phần 5.3 về cách sắp xếp tối ưu trong Tập 3 của Nghệ thuật lập trình máy tính , bao gồm chính xác câu hỏi này' được coi là một gợi ý hoặc một giải pháp? :-)
Steven Stadnicki

3
Giới hạn thực sự là 5 ! = 120 < 2 7 = 128 . Vì vậy, nó có thể (về nguyên tắc). 2cn!5!=120<27=128
vonbrand

Câu trả lời:


23

Chỉ có một cách để bắt đầu quá trình này (và đối với gần như tất cả các quyết định của bạn về những gì cần so sánh trong các bước sau, chỉ có một cách chính xác). Đây là cách để tìm ra nó. Đầu tiên, lưu ý rằng có câu trả lời có thể bạn có thể nhận được để so sánh và 5 ! = 120 hoán vị khác nhau bạn cần phân biệt.27=1285!=120

Việc so sánh đầu tiên rất dễ dàng: bạn phải so sánh hai khóa và vì bạn không biết gì về chúng, nên tất cả các lựa chọn đều tốt như nhau. Vì vậy, giả sử bạn so sánh b , và thấy rằng a b . Bây giờ bạn có 2 6 = 64 câu trả lời có thể còn lại và 60 hoán vị có thể còn lại (vì chúng tôi đã loại bỏ một nửa trong số chúng).abab26=6460

Tiếp theo, chúng ta có thể so sánh d hoặc chúng ta có thể so sánh c với một trong các khóa chúng ta đã sử dụng trong so sánh đầu tiên. Nếu chúng ta so sánh cd , và biết rằng c d , sau đó chúng tôi có 32 câu trả lời còn lại vàcdccdcd32 hoán vị có thể. Mặt khác, nếu chúng ta so sánh c với một , và chúng tôi phát hiện ra rằng một c , chúng tôi có 40 hoán vị có thể còn lại, bởi vì chúng tôi đã loại bỏ 1 / 3 của các hoán vị có thể (những người có c 30caac401/3 ). Chúng tôi chỉ có 32 câu trả lời còn lại có thể, vì vậy chúng tôi không gặp may.cab32

Vì vậy, bây giờ chúng ta biết rằng chúng ta phải so sánh các khóa thứ nhất và thứ hai, và khóa thứ ba và thứ tư. Chúng ta có thể giả sử rằng chúng ta có c d . Nếu chúng ta so sánh e với bất kỳ trong bốn phím, bằng cách lập luận cùng chúng tôi sử dụng trong bước trước, chúng ta có thể chỉ loại bỏ 1 / 3 của hoán vị còn lại, và chúng tôi không gặp may. Vậy ta phải so sánh hai trong số các phím a , b , c , d . Có tính đến sự đối xứng, chúng ta có hai lựa chọn, so sánh ac hoặc so sánh adabcde1/3a,b,c,dacad. Một đối số đếm tương tự cho thấy chúng ta phải so sánh c . Chúng ta có thể giả định mà không mất tính tổng quát rằng một c , và bây giờ chúng tôi có một bmột c d .acacabacd

Vì bạn đã hỏi gợi ý, tôi sẽ không đi qua phần còn lại của cuộc tranh luận. Bạn có bốn so sánh còn lại. Sử dụng chúng một cách khôn ngoan.


Làm thế nào bạn có được sự so sánh đó với c chỉ khiến bạn giảm xuống 40 hoán vị? ac
Robert S. Barnes

1
@Robert: Giả sử bạn có một c . Sau đó, có hai hoán vị của a , b , c phù hợp với các ràng buộc này, a < b < ca < c < b . Đối với mỗi hai hoán vị này, có bốn nơi bạn có thể thêm d và năm địa điểm bạn có thể thêm e . abaca,b,ca<b<ca<c<bde
Peter Shor

8

Bạn có thể tìm thấy điều này trong Nghệ thuật lập trình máy tính vol III, của D.Knuth, nhưng chiến lược là như thế này (tôi sẽ giả sử bạn có mảng ): Nếu bạn muốn đọc gợi ý chỉ hai dòng đầu tiên của câu trả lời của tôi{a,b,c,d,e}

  • Các cặp số nhóm đầu tiên: .(a,b),(c,d)
  • So sánh các cặp để sắp xếp chúng, ví dụ: .a<b,c<d
  • So sánh các yếu tố nhỏ nhất của các cặp, chúng tôi nhận được kết quả, ví dụ .a<c
  • So sánh phần tử cuối cùng , với phần tử lớn hơn trong so sánh cuối cùng ( c ) ec
    • Nếu , dễ kết thúc với 3 so sánh còn lại. Đã kết thúc.e<c
    • Nếu thì bạn nên sắp xếp { b , c , d , e } với kiến ​​thức c < e , c < d . e>c{b,c,d,e}c<e,c<d
      • , nếu d < e rồi Compare(d,e)d<e
        • , nếu b > dCompare(b,d)b>d
          • . Đã kết thúc.Compare(b,e)
        • nếu b<d
          • . Đã kết thúc.Compare(b,c)
      • nếu d>e
        • nếu b > eCompare(b,e)b>e
          • . Đã kết thúc.Compare(b,d)
        • nếu b<e
          • . Đã kết thúc.Compare(b,c)

Tất cả các cách được đề cập ở trên là nguyên nhân của nhiều nhất ba so sánh sau khi so sánh đầu tiên của với c . (có nghĩa là tối đa 7). ec


Bạn có chắc chắn điều này là chính xác? Giả sử bạn nhận được các kết quả sau: a <b, c <d, a <c và sau đó c <e, b <e, c <b và d <e. Các thứ tự a <c <b <d <e và a <c <d <b <e đều phù hợp với chúng. Lý do là b và d không bao giờ được so sánh, ngầm hay rõ ràng. Có lẽ tôi đã nhầm ở đâu đó, nếu vậy xin hãy sửa cho tôi.
George
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.