快速排序不起作用
这是我的快速排序方法的所有代码,它适用于一组 21 个数字,但不适用于我的真实数据集,大约 100000。我不知道出了什么问题,我已经摆弄了两个小时,它即将到期!任何帮助将非常受欢迎
public static void hybridQuicksort( int[] a, int start, int end )
{
final int MIN = 13;
if ( end - start >= MIN )
{
int pivot = findPivot( a, start, end );
pivot = partition ( a, start, end, pivot );
hybridQuicksort( a, start, pivot - 1 );
hybridQuicksort( a, pivot + 1, end);
}
else
{
insertionSort( a, start, end );
}
}
//partitions the array based on the pivot
public static int partition( int[] a, int start, int end, int pivot )
{
int up = start + 1;
int down = end;
while ( up <= down )
{
while ( a[up] <= pivot)
up++;
while ( a[down] > pivot)
down--;
if ( up <= down )
swap( a, up, down );
}
swap( a, start, down );
return up;
}
//finds the first, middle, middle of first and middle, middle of middle and last
//and last numbers and sets their median as the pivot
public static int findPivot( int[] a, int start, int end )
{
//swap the 4 numbers to the start of the array, leaving the first as is
swap( a, start + 1, end - 1 );
swap( a, start + 2, (start + end) / 2);
swap( a, start + 3, end / 4);
swap( a, start + 4, (end / 2) + (end / 4) );
//sort the 5 numbers
insertionSort( a, 0, 5 );
//swap the median to the front, that's the pivot
swap( a, start, start + 2 );
//return the pivot
return a[start];
}
This is all my code for my quicksort method, it works on a set of 21 numbers, but not on my real data set, which is about 100000. I have no idea what is wrong, I've been fiddling for two hours and it is due soon! Any help would be very welcome
public static void hybridQuicksort( int[] a, int start, int end )
{
final int MIN = 13;
if ( end - start >= MIN )
{
int pivot = findPivot( a, start, end );
pivot = partition ( a, start, end, pivot );
hybridQuicksort( a, start, pivot - 1 );
hybridQuicksort( a, pivot + 1, end);
}
else
{
insertionSort( a, start, end );
}
}
//partitions the array based on the pivot
public static int partition( int[] a, int start, int end, int pivot )
{
int up = start + 1;
int down = end;
while ( up <= down )
{
while ( a[up] <= pivot)
up++;
while ( a[down] > pivot)
down--;
if ( up <= down )
swap( a, up, down );
}
swap( a, start, down );
return up;
}
//finds the first, middle, middle of first and middle, middle of middle and last
//and last numbers and sets their median as the pivot
public static int findPivot( int[] a, int start, int end )
{
//swap the 4 numbers to the start of the array, leaving the first as is
swap( a, start + 1, end - 1 );
swap( a, start + 2, (start + end) / 2);
swap( a, start + 3, end / 4);
swap( a, start + 4, (end / 2) + (end / 4) );
//sort the 5 numbers
insertionSort( a, 0, 5 );
//swap the median to the front, that's the pivot
swap( a, start, start + 2 );
//return the pivot
return a[start];
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
假设:
结束为 1000
end/4 是 250
.. 您正在交换排序子集外部的值。
Assumption:
end is 1000
end/4 is 250
.. you are swapping values from outside your sorting-subset.
这看起来不像是家庭作业问题。如果这是一个家庭作业问题,作者会写大约七到十行代码,并附上有效性证明,然后将其提交。这家伙想表现得花里胡哨,结果却在他背后咬了一口。您可以通过他对所谓的“小”间隔进行插入排序的方式来判断。 (提示:阈值间隔大小超过测试数据大小的一半。如果您想很好地测试算法,请给算法一些递归空间。)其次,他正在做额外的工作来找到理想的枢轴。这种复杂性是有代价的。
这是一个工作中的业余爱好者。他需要的不仅仅是一个答案。他需要一种解决难题的方法。快速排序正是这种教育的工具。
这是我的方法。
诀窍是将快速排序编写为快速排序,让它工作,然后担心花哨的特殊技巧。消除小区间插入排序的噪音。只需假设任何大小为零或一的间隔已经排序(这是您的基本情况),然后使用间隔的左端作为枢轴(如经典的原始快速排序)来使分区代码工作,您可能会考虑在一次分区之后打印数据结果,以此来证明它有效。您将通过这种方式培养测试技能。不管怎样,一旦你有了一个有效的快速排序,那么你就可以做一些事情,比如将枢轴选择单独放入一个函数中并进行实现。
祝你好运,享受你的项目。但不要忘记:我们需要计时,尤其是与标准库中的排序例程进行时间比较!
This doesn't look like a homework problem. Were it a homework problem, the author would have written about seven to ten lines of code, with a proof of effectiveness, and turned it in. This guy is trying to be fancy, and it's biting him in the backside. You can tell by the way he drops to insertion-sort for so-called "small" intervals. (Clue: the threshold interval size is more than half the test data size. Give your algorithm some room to recurse if you want to test it well.) Second, there is the extra work he's doing to find an ideal pivot. This kind of complexity comes at a cost.
This is a hobbyist at work. What he needs is not just an answer. He needs an approach to solving hard problems. Quicksort is just the vehicle for that education.
Here's my approach.
The trick is to write Quicksort as Quicksort, get it working, and then worry about fancy special tricks. Kill off the noise about insertion sorting small intervals. Just assume that any interval of size zero or one is already sorted (which is your base case) and then work on making your partitioning code work using the left end of the interval as the pivot (as in classical original Quicksort), and you might consider printing the results of your data after one partitioning pass as a way to show yourself that it works. You'll develop testing skills that way. Anyway, once you have a working quicksort, then you can do things like separate pivot selection into a function and play with the implementation.
Good luck, and enjoy your project. Don't forget, though: We want timings, and especially time comparisons with the sort routine in the standard library!