Về cơ bản, bạn muốn biết liệu có bất kỳ thuật toán sắp xếp nào sẽ không làm giảm so với trường hợp trung bình của nó hay không nếu được cung cấp một hàm so sánh tương tự như:
int Compare(object a, object b) { return Random.Next(-1,1); }
... Trong đó Random.Next () là một số phương thức sẽ tạo ra một số nguyên được tạo ngẫu nhiên giữa một giới hạn bao gồm thấp hơn và giới hạn trên.
Câu trả lời thực sự là hầu hết các thuật toán sắp xếp cơ bản sẽ thực hiện theo trường hợp trung bình của chúng, bởi vì chúng tuân theo ít nhất một trong hai điều kiện sau:
- So sánh giữa hai yếu tố duy nhất không bao giờ được thực hiện hai lần trong sắp xếp và / hoặc
- Trong mỗi lần lặp của sắp xếp, vị trí chính xác của ít nhất một phần tử được xác định và do đó phần tử đó không bao giờ được so sánh lại.
Chẳng hạn, SelectionSort lặp qua danh sách phụ của các phần tử chưa được sắp xếp, tìm phần tử "ít nhất" và / hoặc "lớn nhất" (bằng cách so sánh từng phần tử với phần tử lớn nhất cho đến nay), đặt nó vào vị trí chính xác và lặp lại. Kết quả là, ngay cả với một bộ so sánh không xác định, vào cuối mỗi lần lặp, thuật toán sẽ tìm thấy một giá trị mà nó nghĩ là ít nhất hoặc lớn nhất, hoán đổi nó với phần tử ở vị trí mà nó đang cố gắng xác định và không bao giờ xem xét yếu tố đó một lần nữa, do đó nó tuân theo Điều kiện 2. Tuy nhiên, A và B có thể được so sánh nhiều lần trong quá trình này (như ví dụ cực đoan nhất, hãy xem xét một vài lượt của SelectionSort trên một mảng được sắp xếp theo thứ tự ngược lại) vì vậy nó vi phạm Điều kiện 1 .
MergeSort tuân theo Điều kiện 1 nhưng không phải 2; khi các mảng con được hợp nhất, các phần tử trong cùng một mảng con (ở bên trái hoặc bên phải) không được so sánh với nhau bởi vì chúng đã được xác định rằng các phần tử ở bên đó của mảng được sắp xếp theo thứ tự; thuật toán chỉ so sánh phần tử chưa hợp nhất ít nhất của mỗi phần tử con khác để xác định phần tử nào nhỏ hơn và sẽ đi tiếp trong danh sách được hợp nhất. Điều này có nghĩa là bất kỳ hai đối tượng duy nhất A và B sẽ được so sánh với nhau tối đa một lần, nhưng không biết chỉ số "cuối cùng" của phần tử nào trong bộ sưu tập đầy đủ cho đến khi thuật toán hoàn tất.
Chèn cũng chỉ tuân theo Điều kiện 1 mặc dù chiến lược tổng thể và độ phức tạp của nó trông giống như SelectionSort. Mỗi phần tử chưa được sắp xếp được so sánh với các phần tử được sắp xếp, trước hết, cho đến khi tìm thấy phần tử nhỏ hơn phần tử được kiểm tra. phần tử được chèn vào thời điểm đó, và sau đó phần tử tiếp theo được xem xét. Kết quả là thứ tự tương đối của bất kỳ A và B nào được xác định bằng một so sánh và không bao giờ so sánh giữa A và B đó, nhưng vị trí cuối cùng của bất kỳ yếu tố nào cũng không thể được biết cho đến khi tất cả các yếu tố được xem xét.
QuickSort tuân theo cả haiĐiều kiện. Ở mỗi cấp độ, một trục được chọn và sắp xếp sao cho phía "bên trái" chứa các phần tử nhỏ hơn trục và bên "bên phải" chứa các phần tử lớn hơn trục. Kết quả của cấp đó là QuickSort (trái) + p Pivot + QuickSort (phải) về cơ bản có nghĩa là vị trí của phần tử trục được biết đến (một chỉ số lớn hơn chiều dài của bên trái), trục không bao giờ được so sánh với bất kỳ phần tử nào khác sau khi nó được chọn làm trục (nó có thể được so sánh với các yếu tố trục trước đó, nhưng các yếu tố đó cũng được biết đến và không được bao gồm trong bất kỳ phân đoạn nào), VÀ bất kỳ A và B nào nằm ở phía đối diện của trục đều không bao giờ so. Trong hầu hết các triển khai QuickSort thuần túy, trường hợp cơ sở là một yếu tố, tại đó chỉ số hiện tại của nó là chỉ mục cuối cùng và không có so sánh nào được thực hiện.
Loại so sánh duy nhất tôi có thể nghĩ rằng sẽ không tuân theo một trong hai điều kiện là BubbleSort không được tối ưu hóa. Nếu loại sắp xếp không chấp nhận rằng các phần tử X lớn nhất nằm ở vị trí thích hợp của chúng sau khi chạy X vượt qua và / hoặc sử dụng thẻ "kiểm tra hai lần" để xác minh danh sách được sắp xếp, sắp xếp sẽ chỉ được coi là "hoàn thành" khi bộ so sánh ngẫu nhiên đã trả về -1 hoặc 0 cho mỗi hai phần tử liền kề trong danh sách trong khi vượt qua và do đó không có giao dịch hoán đổi nào được thực hiện (một sự kiện, nếu thực sự ngẫu nhiên, sẽ xảy ra với xác suất ; đối với một danh sách tương đối nhỏ gồm 25 yếu tố, đó là cơ hội trong năm 2000, trong khi đối với 100 yếu tố thì xác suất là 3,7 * 10 -18( 2 / 3 )N- 1). Khi giá trị tuyệt đối tối đa của kết quả của bộ so sánh tăng lên, xác suất cho bất kỳ một so sánh nào trả về âm hoặc bằng 0 sẽ giảm xuống 0,5, làm cho cơ hội kết thúc thuật toán ít có khả năng hơn (cơ hội 99 đồng xu lật tất cả các đầu hạ cánh , về cơ bản, cái này có nghĩa là, 1 trong 1,2 * 10 30 )
EDIT A LATER LỚN THỜI GIAN: Có một vài "loại" được thiết kế cụ thể như các ví dụ về những việc không nên làm mà kết hợp một bộ so sánh ngẫu nhiên; có lẽ nổi tiếng nhất là BogoSort. "Đưa ra một danh sách, nếu danh sách không theo thứ tự, hãy xáo trộn danh sách và kiểm tra lại". Về mặt lý thuyết, cuối cùng nó sẽ đạt được sự hoán vị đúng của các giá trị, giống như "BubbleSort không được tối ưu hóa" ở trên, nhưng trường hợp trung bình là thời gian giai đoạn (N! / 2) và vì vấn đề sinh nhật (sau khi đủ hoán vị ngẫu nhiên trở nên có khả năng gặp phải các hoán vị trùng lặp hơn so với các hoán vị duy nhất) có khả năng thuật toán không bao giờ hoàn thành để chính thức thuật toán không bị ràng buộc theo thời gian.