【发布时间】:2020-04-30 12:32:23
【问题描述】:
我已经尽我所能实现了我教科书中的快速排序算法,其中包含三个枢轴选择函数的中值 - 数据抽象和问题解决,Walls and Mirrors 第 7 版。它部分工作 - 除了数组中元素的结果并非全部按正确的升序排列。由于某种原因,在某些数字序列以正确的顺序放置后,突然一些整数将在他们自己的间隔中出现乱序,然后它将恢复为之后以正确的升序继续,然后再次以一些无序的整数重复。我一直遵循教科书,并且搜索了许多其他解决方案,并注意到了一些细微的差异(例如,我的枢轴选择功能需要 3 个参数,而我见过的所有其他功能需要两个参数)。我试图弄清楚它无济于事,我认为这在逻辑上是次要的,我似乎无法从文本中的伪代码中推断出来。
template<typename ItemType>
void sortFirstMiddleLast(ItemType theArray[], int first, int middle, int last) {
ItemType temp, temp2, temp3;
if (theArray[first] > theArray[middle]) {
temp = theArray[first];
theArray[first] = theArray[middle];
theArray[middle] = temp;
}
if (theArray[middle] > theArray[last]) {
temp2 = theArray[last];
theArray[last] = theArray[middle];
theArray[middle] = temp2;
}
if (theArray[first] > theArray[middle]) {
temp3 = theArray[first];
theArray[first] = theArray[middle];
theArray[middle] = temp3;
}
}
template<typename ItemType>
int partition(ItemType theArray[], int first, int last)
{
ItemType temp;
//Choose pivot and reposition it
int mid = first + (last - first) / 2;
sortFirstMiddleLast(theArray, first, mid, last);
//Interchange
temp = theArray[last - 1];
theArray[last - 1] = theArray[mid];
theArray[mid] = temp;
int pivotIndex = last - 1;
ItemType pivot = theArray[pivotIndex];
//Determine the regions S sub 1 and S sub 2
int indexFromLeft = first + 1;
int indexFromRight = last - 2;
bool done = false;
while (!done) {
//locate first entry on left that is >= pivot
while (theArray[indexFromLeft] < pivot)
indexFromLeft = indexFromLeft + 1;
//locate first entry on right that is <= pivot
while (theArray[indexFromRight] > pivot)
indexFromRight = indexFromRight - 1;
//now indexFromLeft has a new index subscript and indexFromRight has a new index subscript
//compare the two indexes
if (indexFromLeft < indexFromRight) {
ItemType temp2 = theArray[indexFromRight];
theArray[indexFromRight] = theArray[indexFromLeft];
theArray[indexFromLeft] = temp2;
indexFromLeft = indexFromLeft + 1;
indexFromRight = indexFromRight - 1;
}
else
done = true;
}
//Place pivot in proper position between Ssub1 and Ssub2 and mark its new location
pivot = theArray[pivotIndex];
theArray[pivotIndex] = theArray[indexFromLeft];
theArray[indexFromLeft] = pivot;
pivotIndex = indexFromLeft;
return pivotIndex;
}
template<typename ItemType>
void quickSort(ItemType theArray[], int first, int last) {
//sift out small arrays
int n = last - first + 1;
if ( n < MIN_SIZE){//array is of size < 10 so use insertion sort
insertionSort(theArray, n);
}
else {
//Make the partition : S1 | Pivot | S2
int pivotIndex = partition(theArray, first, last);
//Sort subarrays S1 and S2
quickSort(theArray, first, pivotIndex - 1);
quickSort(theArray, pivotIndex + 1, last);
}
}
const int RAND_NUMSIZE = 51; // for quick sort array size (random number gen 1-50)
const int MIN_SIZE = 10;//specify size of smallest array to use quick sort
int main()
{
int array5[RAND_NUMSIZE] = { 50, 41, 45, 43, 48, 40, 47, 42, 46, 49, 44, 39, 31, 37, 35, 33, 32, 38, 33, 34, 30, 36, 21, 29, 20, 22, 28, 23, 27, 24, 26, 25, 19, 13, 18, 14, 17, 15, 16, 12, 10, 11, 7, 8, 1, 4, 2, 6, 3, 9, 5 }
std::cout << "\nThe quick sort array before sorting: \n";
for (int i = 0; i < RAND_NUMSIZE; i++) {
std::cout << array5[i] << ' ';
}
//call quick sort
quickSort(array5, 0, RAND_NUMSIZE - 1);
std::cout << "\nThe quick sort array after sorting: \n";
for (int i = 0; i < RAND_NUMSIZE; i++) {
std::cout << array5[i] << ' ';
}
显示我正在谈论的结果的图片链接:
【问题讨论】:
-
除了,数组中元素的结果并非都按正确的升序排列。 -- 这是一个很大的except。你的排序不是排序。 我试图弄清楚它无济于事, -- 使用编译器附带的调试器,单步执行程序,直到你看到程序做了一些意想不到的事情。
-
其次,排序 5 或 6 个数字,而不是 51 个数字。如果您不能对 5 或 6 个数字进行排序,那么您将不会对 51 个数字进行排序。对这么多数字进行排序会让你忘记正在发生的事情。用最少的元素找出导致错误的顺序。然后专注于较小的值序列。
-
感谢 Paul 的洞察力,我将数组减少到约 10 个元素,结果相同......前几个数字的顺序正确,然后发生了无序的 int 序列。我在想我必须做一个 for 循环来遍历数组并将 if 子句嵌套在我的 sortFirstMiddleLast 函数中。
-
要查看问题所在,请选择数组中的第一个数字作为基准,而不是三的中位数。当你这样做时,排序是否有效?如果是这样,那么快速排序的基础是好的,而你的枢轴选择策略是不正确的。如果当您仅选择第一个值作为基准时排序不起作用,那么是您的排序例程有问题(并且有很多用 C++ 编写的快速排序实现可用作参考)。
-
想通了...我的快速排序函数中发生了错误..我的基本情况没有按应有的方式实现,因此它仍在尝试对无法使用的数组大小使用递归.我将其纠正为对大小小于 4 的子数组进行排序,而无需使用分区函数或快速排序递归,仅使用 sortFirstMiddleLast 即可。我应该回答我自己的问题还是删除它?这是我第一次这样做,我注意到我的代表已经出错了。
标签: c++ arrays sorting quicksort median