Tôi đang cố gắng viết một quicksort cho sự chỉnh sửa của riêng tôi. Tôi đang sử dụng pseudocode on wikipedia làm hướng dẫn. Mã của tôi hoạt động. Có vẻ như nó sẽ chạy trong thời gian O (n log n). Tôi đã thử thực sự định thời gian mã của mình để kiểm tra độ phức tạp (tức là, khi tôi tăng gấp đôi kích thước đầu vào, thời gian chạy có tăng khoảng n log n), nhưng tôi vẫn không chắc chắn.Đây có phải là QuickSort không?
Mã của tôi có vẻ khá đơn giản. Tôi thực hiện sắp xếp tại chỗ. Các triển khai khác mà tôi đã thấy sử dụng một hàm phân vùng, mà tôi không có. Điều này làm cho tôi nghĩ rằng tôi đã thực hiện một số thuật toán sắp xếp khác. Đây có phải là thuật toán quicksort không?
public static void QuickSortInPlace(int[] arr)
{
QuickSortInPlace(arr, 0, arr.Length - 1);
}
private static void QuickSortInPlace(int[] arr, int left, int right)
{
if (left < right)
{
//move the middle int to the beginning and use it as the pivot
Swap(arr, left, (left + right)/2);
int pivotIndex = left;
int pivot = arr[pivotIndex];
int min = left + 1;
int max = right;
for (int i = min; i <= max; i++)
{
if (arr[i] > pivot)
{
Swap(arr, i, max);
max--; //no longer need to inspect ints that have been swapped to the end
i--; //reset the loop counter to inspect the new int at the swapped position
}
}
//move pivot to its sorted position
Swap(arr, max, pivotIndex);
//recurse on the sub-arrays to the left and right of the pivot
QuickSortInPlace(arr, left, max - 1);
QuickSortInPlace(arr, max + 1, right);
}
}
Phiên bản thứ hai dựa trên phản hồi của Dukeling.
public static void QuickSortInPlace3(int[] arr, int min, int max)
{
if (min < max)
{
int pivotIndex = min;
int pivot = arr[pivotIndex];
int left = min;
int right = max;
while (left <= right)
{
while (arr[left] < pivot)
left++;
while (arr[right] > pivot)
right--;
if (left <= right)
{
Swap(arr, left, right);
left++;
right--;
}
}
QuickSortInPlace3(arr, min, right);
QuickSortInPlace3(arr, left, max);
}
}
Tôi đang gặp rắc rối tìm hiểu giả bạn đã dán vào một bất biến vòng lặp cho Sắp xếp nhanh là sau một lần lặp, trục chính ở đúng nơi. Sử dụng phiên bản thứ hai của tôi mà tôi dán ở trên, tôi không tìm thấy điều này là đúng (mặc dù mã hoạt động). Đây là một mẫu chạy: đầu vào {'3', 2,4,1,5} -> trao đổi đầu tiên {1,2,' 4', 3,5} -> trao đổi thứ hai {1,2,3,4,5 }. Tôi đã làm nổi bật các trục xoay ở mỗi bước. Sau lần hoán đổi đầu tiên, trục đầu tiên '3' không ở vị trí cuối cùng của nó. Điều đó vi phạm các bất biến vòng lặp, và sau khi trao đổi thứ hai, mảng là theo thứ tự. Bạn có biết tại sao không? – user2023861
Không quan trọng vị trí của phần tử trục. Nếu nó ở bên trái, nó sẽ là yếu tố lớn nhất trong subarray đó và được đặt ở vị trí bên phải nhất. Nếu nó ở bên phải, nó sẽ là nhỏ nhất và được đặt ở vị trí ngoài cùng bên trái. Vì vậy, một trong hai cách, nó kết thúc ở giữa. Mặc dù đặt nó ở chính giữa kết quả trong một vài so sánh ít hơn, như bạn sẽ không bao giờ so sánh nó với bất cứ điều gì một lần nữa. – Dukeling