Java và .NET: Tại sao các thuật toán sắp xếp khác nhau được sử dụng theo mặc định?


19

Chỉ cần tự hỏi tại sao Java.NET Frameworksử dụng thuật toán sắp xếp khác nhau theo mặc định.

Trong Java Array.Sort() sử dụng thuật toán Hợp nhất theo mặc định và như Wikipedia.com nói:

Trong Java, các phương thức Arrays.sort () sử dụng sắp xếp hợp nhất hoặc quicksort được điều chỉnh tùy thuộc vào kiểu dữ liệu và để chuyển đổi hiệu quả thực hiện sang sắp xếp chèn khi sắp xếp ít hơn bảy phần tử mảng

Trong .NET Framework Array.Sort/List.Sort() sử dụng Sắp xếp nhanh làm thuật toán sắp xếp mặc định ( MSDN ):

List.Sort () sử dụng Array.Sort, sử dụng thuật toán QuickSort. Việc thực hiện này thực hiện một loại không ổn định; nghĩa là, nếu hai phần tử bằng nhau, thứ tự của chúng có thể không được giữ nguyên. Ngược lại, một loại ổn định bảo tồn thứ tự các phần tử bằng nhau.

Bằng cách nhìn vào bảng "So sánh các thuật toán" tuyệt vời, chúng ta có thể thấy rằng cả hai thuật toán có hành vi khá khác nhau từ các quan điểm về trường hợp xấu nhất và sử dụng bộ nhớ:

nhập mô tả hình ảnh ở đây

Cả hai Java.NETlà các Khung tuyệt vời để phát triển Giải pháp Doanh nghiệp, cả hai đều có nền tảng để phát triển nhúng. Vậy tại sao họ lại sử dụng thuật toán sắp xếp khác nhau theo mặc định, bạn có suy nghĩ gì không?


1
Để thảo luận thêm về so sánh giữa hai loại này, hãy xem stackoverflow.com/q/680541/866022
yoozer8

Câu trả lời:


10

Có tính quyết định như chính máy tính, kỹ thuật máy tính không phải là một môn khoa học chính xác. Hai người, được đưa ra cùng một miền vấn đề, sẽ thực hiện phân tích và phát triển hai giải pháp khác nhau thỏa mãn mọi ràng buộc của vấn đề. Có thể khó hoặc không thể xác định theo kinh nghiệm trong số này là "tốt hơn" trong trường hợp chung.

Tôi đoán là .NET QuickSort được xếp chồng lên trên một thứ gì đó trong MFC hoặc Windows API và có thể được thừa hưởng từ các phiên bản Windows cũ hơn nhiều, nơi mà lợi thế đa luồng của MergeSort thậm chí sẽ không được xem xét cho các máy tính của ngày. ( EDIT: không, mặc dù các nhà phát triển của Microsoft đã là fanboy của QuickSort trong một thời gian dài, bằng chứng là sự lựa chọn sắp xếp thực hiện này kể từ MS-DOS).

Java, không thể sử dụng bất kỳ triển khai cụ thể nền tảng nào vì Java được thiết kế từ đầu để hoàn toàn độc lập với nền tảng, đã đi theo một cách khác. Ai biết tại sao MergeSort lại đứng đầu; Tôi đoán là việc triển khai đã giành được một số loại cạnh tranh hiệu suất so với một số loại khác mà các nhà phát triển đã đưa ra, hoặc nếu không thì MergeSort không gian O (n) trông tốt nhất trên giấy về hiệu suất trong trường hợp tốt nhất và trường hợp xấu nhất (MergeSort không có gót chân của Achilles liên quan đến lựa chọn thành phần như QuickSort và trường hợp tốt nhất của nó là một danh sách sắp xếp gần trong khi đó thường là điều tồi tệ nhất của QuickSort). Tôi nghi ngờ lợi ích đa luồng đã được xem xét ban đầu, nhưng việc triển khai hiện tại có thể là đa luồng.


1
List<T>.Sorttrong .NET sử dụng một phương thức riêng được triển khai trong CLR (nếu bạn không sử dụng trình so sánh tùy chỉnh), nhưng không phụ thuộc vào các thư viện hệ điều hành.
Joey

1
@Keith - .NET không được đặt lên trên bất kỳ thứ gì và được thiết kế độc lập với nền tảng. Bạn có thể xem triển khai ngay tại đây: github.com/dotnet/coreclr/blob/master/src/mscorlib/src/System/ Kẻ
Robert MacLean

@RobertMacLean - ".NET không được xếp chồng lên trên bất cứ thứ gì" không phải là một tuyên bố đúng, mặc dù bạn đã chứng minh rằng hàm Sắp xếp trong câu hỏi là mã "được quản lý" hoàn toàn. Các phần lớn của .NET, bao gồm hỗ trợ mã hóa, thư viện GUI trên máy tính để bàn Windows, giao diện API của Windows (bao gồm kiểm soát quy trình và luồng) đều dựa trên mã không được quản lý trước đó bao gồm cả MFC. Họ chỉ đơn giản là phải như vậy; Bản thân Windows chỉ có một thành phần .NET rất nhỏ trong cơ sở mã của nó, phần còn lại không được quản lý
KeithS

Các nhà phát triển của Microsoft vẫn là những người hâm mộ QuickSort đã được chứng minh qua các triển khai khác, vì QuickSort là thuật toán được lựa chọn kể từ MS-DOS và điều này sẽ ảnh hưởng đến quyết định của họ trong việc sắp xếp .NET với thuật toán này.
KeithS

Câu trả lời này là sai, tôi thực sự bị sốc.
user9993

17

Các nhóm phát triển khác nhau ở hai công ty khác nhau đã đưa ra kết luận khác nhau về trường hợp sử dụng thông thường cho các khung và thành phần của họ và đã quyết định thực hiện theo đó.

Về cơ bản, mỗi công ty đã phân tích, xem xét cơ sở khách hàng của họ và đưa ra các quyết định khác nhau cho phù hợp.

Bạn không thể mong đợi phân tích của các công ty và nhóm khác nhau, sử dụng các giả định và dữ liệu thô khác nhau để đưa ra kết luận giống nhau.


5
Hoặc thậm chí các giả định và dữ liệu thô tương tự. . .
Wyatt Barnett

Vâng, đó có lẽ chỉ là thói quen - microsoft đã quen với việc sử dụng quicksort (không ổn định), java muốn sử dụng loại ổn định ... và loại hợp nhất là loại ổn định nhanh nhất được biết đến ...
rogerdpack

12

Câu hỏi này hơi lỗi thời, vì Java hiện sử dụng Timsort (kể từ Java 7)

Trong số các thuật toán cụ thể được đề cập:

  • Quicksort có hiệu suất trường hợp xấu nhất không thuận lợi ở O (n ^ 2), nhưng nhẹ hơn / ít tiêu tốn bộ nhớ hơn nên cung cấp hiệu suất tốt hơn trong trường hợp điển hình.

  • Mergesort đã đảm bảo hiệu suất trong trường hợp xấu nhất tại O (n log n), nhưng mang nhiều yêu cầu về bộ nhớ và chi phí hơn một chút. Nó cũng tự động ổn định (tức là duy trì các phần tử bằng nhau theo cùng một thứ tự).

Các nhà thiết kế Java nói chung có vẻ bảo thủ / tập trung hơn vào "điều đúng đắn", do đó, không có gì đáng ngạc nhiên khi họ chọn Mergesort trong số hai vì nó mang lại sự đảm bảo tốt hơn.

Không chắc chắn tại sao Microsoft chọn Quicksort, có thể họ mặc dù điều đó sẽ làm cho họ trông đẹp hơn trong một số điểm chuẩn vi mô?

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.