Có tài nguyên nào về cách mergeSort được sử dụng bởi Arrays.sort (Object [] a) được triển khai không? Trong khi nó được ghi nhận khá tốt, tôi có một thời gian khó hiểu nó (đặc biệt là tại sao src và dest được chuyển đổi khi mergeSort() nhận được đệ quy gọi).Arrays.sort (Object [] a) - được triển khai như thế nào?
Trả lời
Here is the source trong số java.util.Arrays
.
Thực ra, bạn có mã nguồn đó trong JDK - chỉ cần mở java.util.Arrays
trong IDE của bạn và mã nguồn + nhận xét sẽ xuất hiện. Nếu bạn không có IDE, hãy xem JDK_HOME\src.zip
Sau đó, hãy đặt nó trong IDE của bạn và theo dõi cách hoạt động.
- breakpoint đặt (và chạy một chương trình trong chế độ gỡ lỗi)
- sử dụng
System.out.println(..)
- phần thay đổi của nó để xem cách họ được phản ánh.
- đọc được sự chú ý wikipedia article about merge sort
- trả tiền để nhận xét này:
// Recursively sort halves of dest into src
Nó ** xuất hiện ** OP đã thấy nguồn (vì anh ta đề cập đến thực tế là các mảng 'src' và' dest' được chuyển khi được gọi đệ quy gọi) nhưng có một thời gian khó hiểu logic. –
hm, vâng. Tôi đã đưa ra một số gợi ý về cách hiểu nó tốt hơn. – Bozho
Tôi có thể là sai tất nhiên ... Dù sao, tôi sẽ đề nghị OP sử dụng trình gỡ lỗi * người đàn ông nghèo * (đặt một số System.out.println trong thuật toán), nhưng bạn đánh tôi với nó! –
Tôi từng có sự nhầm lẫn tương tự với bạn. Theo hiểu biết của tôi, lý do cho việc chuyển đổi này rất đơn giản - thực hiện theo bước kết hợp dễ dàng hơn. Không có phép thuật.
private static void mergeSortWithoutSwitch(Object[] src, Object[] dest, int low, int high, int off) {
int length = high - low;
// Insertion sort on smallest arrays
if (length < INSERTIONSORT_THRESHOLD) {
for (int i = low; i < high; i++)
for (int j = i; j > low && ((Comparable) dest[j - 1]).compareTo(dest[j]) > 0; j--)
swap(dest, j, j - 1);
return;
}
// Recursively sort halves of dest into src
int destLow = low;
int destHigh = high;
low += off;
high += off;
int mid = (low + high) >>> 1;
mergeSortWithoutSwitch(src, dest, low, mid, off);
mergeSortWithoutSwitch(src, dest, mid, high, off);
// If list is already sorted, just copy from src to dest. This is an
// optimization that results in faster sorts for nearly ordered lists.
if (((Comparable) dest[mid - 1]).compareTo(dest[mid]) <= 0) {
return;
}
// Merge sorted halves (now in src) into dest
for (int i = destLow, p = low, q = mid; i < destHigh; i++) {
if (q >= high || p < mid && ((Comparable) dest[p]).compareTo(dest[q]) <= 0)
src[i] = dest[p++];
else
src[i] = dest[q++];
}
// copy back
for (int i = destLow; i < destHigh; i++) {
dest[i] = src[i];
}
}
Trên đây là việc triển khai mà không cần chuyển đổi, từ mã, bạn có thể thấy chúng tôi cần thêm một bước nữa khi sao chép - sao chép lại. Tôi nghĩ rằng việc đặt tên tham số trong mergeSort là một chút nhầm lẫn, vì src là mảng phụ chỉ được sử dụng trong bước sáp nhập, nên tốt hơn nên đặt tên nó bằng aux (Chúng ta thậm chí có thể loại bỏ nó khỏi chữ ký phương thức và tạo một biến cục bộ khi hợp nhất). Và dest là mảng kết quả.
- 1. Arrays.sort (object []) không được ném ClassCastException
- 2. OpenID được triển khai như thế nào?
- 3. HttpSession được triển khai như thế nào?
- 4. Phương thức hashCode() trong lớp Object được triển khai như thế nào?
- 5. Lớp Object được triển khai như thế nào (các phương thức như hashCode và các trường nội bộ)?
- 6. C# Generics được triển khai như thế nào?
- 7. Các tham chiếu yếu được triển khai như thế nào?
- 8. GetHashCode() được triển khai cho Int32 như thế nào?
- 9. Facebook Chat Heads được triển khai như thế nào?
- 10. Phạm vi Lexical được triển khai như thế nào?
- 11. IO không chặn được triển khai như thế nào?
- 12. Atan2 được triển khai bằng .NET như thế nào?
- 13. Các khối try/catch được triển khai như thế nào?
- 14. LLVM isa <> được triển khai như thế nào?
- 15. Chuỗi string.find được triển khai như thế nào trong CPython?
- 16. Thuộc tính phụ thuộc được triển khai như thế nào?
- 17. Máy tính Google được triển khai như thế nào?
- 18. Các mảng được triển khai trong Perl như thế nào?
- 19. Bản đồ băm JavaScript được triển khai như thế nào?
- 20. Các mutex được triển khai như thế nào?
- 21. Các mảng được triển khai trong java như thế nào?
- 22. GMail triển khai Comet như thế nào?
- 23. Tại sao Arrays.sort lấy Object [] thay vì Comparable []?
- 24. Versioning a Ruby Object
- 25. Việc triển khai BigNums hoạt động như thế nào?
- 26. Bạn sẽ triển khai đuôi hiệu quả như thế nào?
- 27. Forth triển khai từ điển như thế nào? (tranh cãi)
- 28. Từ khóa java được đồng bộ hóa được triển khai như thế nào?
- 29. Triển khai Django: Bạn làm như thế nào?
- 30. Các ứng dụng Java được triển khai như thế nào trong "thế giới thực"?
http://www.docjar.com/html/api/java/util/Arrays.java.html đây là mã nguồn – Bozho
Bozho, bạn nên đăng câu trả lời đó! – Will
Có vẻ như công việc thực sự bắt đầu trên dòng 486. – MatrixFrog