我目前的QuickSort实现,将数据透视表设置为数组中的最后一个元素,导致堆栈溢出异常。将它设置为中间元素,或最左边,工作正常但不正确。我真的想了解原因。
我目前正在学习数据结构和算法,并且我真的想要了解算法工作方式的复杂性。我已经尝试逐步解决以下问题,但递归正在扼杀我。
基本上我将我的枢轴设置为数组中的最后一个元素,并找到小于枢轴的所有元素,并向左增加成为墙。所有更大的元素都交换到右边。
这是我的解决方案
public static void QuickSort_Recursive(int[] array, int left, int right)
{
// only proceed if left is less than right
if(left < right)
{
// get index for left and right barrier
int pivotIndex = Partition(array, left, right);
// sort left
QuickSort_Recursive(array, left, pivotIndex - 1);
// sort right
QuickSort_Recursive(array, pivotIndex, right);
}
}
public static int Partition(int[] array, int left, int right)
{
// get pivot as last element
int pivot = array[right];
// continue until left passes right
while (left <= right)
{
// continue with left side until you find an element greater than pivot
while(array[left] < pivot)
{
left++;
}
// Continue with right until you find an element less than the pivot
while(array[right] > pivot)
{
right--;
}
// Only swap if left is less than right
if(left <= right)
{
// swap left and right
Swap(array, left, right);
// Increment left and decrement right
left++;
right--;
}
}
return left;
}
任何人都可以帮助我理解为什么将它设置为最正确的元素会导致堆栈溢出异常吗?
编辑:下面是一个与最合适的枢轴一起工作的实现,但是它们的关键是1)它在交换时不包括交换枢轴2)只移动左指针,以便跟踪低位和高位之间的障碍位置3)不移动两个指针
// Make starting pivot the last one for now
int pivot = array[right];
int leftWall = left;
// Go through array until index before pivot is reached
for (int i = left; i < right; i++)
{
// If item at array[i] is less than or equal to pivot then switch with leftwall
if(array[i] <= pivot)
{
// Swap positions with leftWall
Swap_Memory(array, i, leftWall);
// Increment leftwall position
leftWall += 1;
}
}
// Swap pivot with whatever value is the top lowest number (pivot is 'right' in this case)
Swap_Memory(array, leftWall, right);
// return leftwall as pivot
// Leftwall is barrier between values lower than pivot and those higher
return leftWall;
答案 0 :(得分:0)
问题在于您的分区实施。 您必须以这样的方式进行分区,即pivot的索引左侧的所有元素都应小于pivot元素。 以下两件事必须在代码中解决:
标准快速分区分区如下所示:
public static void QuickSort_Recursive(int[] array, int left, int right)
{
// only proceed if left is less than right
if(left < right)
{
// get index for left and right barrier
int pivotIndex = Partition(array, left, right);
// sort left
QuickSort_Recursive(array, left, pivotIndex-1);
// sort right
QuickSort_Recursive(array, pivotIndex+1, right);
}
}
public static int Partition(int[] array, int left, int right)
{
// get pivot as last element
int pivot = array[right];
int i = left - 1;
for (int j = left; j <= right - 1; j++) {
if (array[j] <= pivot) {
i++;
// Make sure all the elements left of pivot index is less
swap(array[i], array[j]);
}
}
//Move the pivot to the selected index and return its index
swap(array[i+1], pivot);
return i + 1;
}
希望它有所帮助!