我正在尝试粗略地对QuickSorts(Single Pivot,3-way和Dual Pivot)的性能进行基准测试。
问题1: 我担心在执行3路分区时我遗漏了一些东西。在针对随机输入(1000万)数字的几次运行中,我可以看到单个枢轴总是表现更好(尽管1000万个数字的差异大约为100毫秒)。
据我所知,3路的整个目的不是重复键上的0(n ^ 2)性能 - 当我针对重复输入运行它时非常明显。但是,为了处理重复数据,3路是否会受到轻微的惩罚?或者我的实施不好?
重复数据:
随机数据:
问题2:
Dual Pivot实现(下面的链接)不能很好地处理重复项。它需要0(n ^ 2)的时间来执行。快进是否有好方法。我可以看到我们可以检查枢轴是否相等并增加pivot1直到它与pivot2不同。这是一个公平的实施吗?
else if (pivot1==pivot2){
while (pivot1==pivot2 && lowIndex<highIndex){
lowIndex++;
pivot1=input[lowIndex];
}
}
实施链接:
根文件夹:https://github.com/arunma/dsa/tree/master/src/basics/sorting/quick
QuickSort(Single Pivot):https://github.com/arunma/dsa/blob/master/src/basics/sorting/quick/QuickSortBasic.java
QuickSort(3路分区): https://github.com/arunma/dsa/blob/master/src/basics/sorting/quick/QuickSort3Way.java
QuickSort(Dual Pivot): https://github.com/arunma/dsa/blob/master/src/basics/sorting/quick/QuickSortDualPivot.java
TestCase: https://github.com/arunma/dsa/blob/master/src/basics/sorting/quick/QuickSortTest.java
答案 0 :(得分:0)
首先摆脱构造函数中的后缀以获得正确的比较。
其次,行为是预期的,因为在基本版本中,如果您在两侧找到合适的候选者,即在QuickSortBasic.java
,您只进行切换。 while (true){
while (less(input[++i], input[pivotIndex])){
if (i==highIndex) break;
}
while (less (input[pivotIndex], input[--j])){
if (j==lowIndex) break;
}
if (i>=j) break;
exchange(input, i, j);
}
而3way版本你正在进行切换,除非元素等于pivot,即在QuickSort3Way.java中
while (i<=gt){
if (less(input[i],pivotValue)){
exchange(input, i++, lt++);
}
else if (less (pivotValue, input[i])){
exchange(input, i, gt--);
}
else{
i++;
}
}