Java 递归快速排序比迭代快速排序更快
我一直在比较递归快速排序和迭代快速排序的性能,似乎我的递归快速排序始终比我的迭代版本快。我只是想知道是否有什么原因可以让递归版本更快?根据我的理解,迭代版本应该执行得更快,因为它避免了递归调用的成本 递归快速排序实现Java 递归快速排序比迭代快速排序更快,java,sorting,recursion,quicksort,Java,Sorting,Recursion,Quicksort,我一直在比较递归快速排序和迭代快速排序的性能,似乎我的递归快速排序始终比我的迭代版本快。我只是想知道是否有什么原因可以让递归版本更快?根据我的理解,迭代版本应该执行得更快,因为它避免了递归调用的成本 递归快速排序实现 int Pivot = 1; QuickSort cleanRun = new QuickSort(runArray, Pivot); int last = runArray.length - 1; long start = System.nanoTime(); cleanRun.
int Pivot = 1;
QuickSort cleanRun = new QuickSort(runArray, Pivot);
int last = runArray.length - 1;
long start = System.nanoTime();
cleanRun.quickSort(0, last);
long end = System.nanoTime();
QuickSortStack cleanRun = new QuickSortStack(runArray);
int last = runArray.length - 1;
long start = System.nanoTime();
cleanRun.explicitStackingQuicksortCustomPivot(runArray);
long end = System.nanoTime();
递归快速排序类
public class QuickSort extends SortingAlgorithm {
public QuickSort(int[] l, int pivot) {
super(l);
}
public int[] getL() {
return l;
}
public void quickSort(int first, int last) {
int splitPoint;
if (first < last) {
splitPoint = split(first, last);
quickSort(first, splitPoint - 1);
quickSort(splitPoint + 1, last);
}
}
private int split(int first, int last) {
int splitPoint, unknown;
int x;
int temp;
int temp2;
x = l[first];
splitPoint = first;
for (unknown = first + 1; unknown <= last; unknown++) {
if (l[unknown] < x) {
splitPoint = splitPoint + 1;
//interchange(splitPoint, unknown);
temp = l[splitPoint];
l[splitPoint] = l[unknown];
l[unknown] = temp;
}
}
temp = l[first];
l[first] = l[splitPoint];
l[splitPoint] = temp;
return splitPoint;
}
}
public class QuickSortStack extends SortingAlgorithm {
public QuickSortStack(int[] l) {
super(l);
}
public int[] getL() {
return l;
}
/**
*
* @param l
*/
public void explicitStackingQuicksortCustomPivot(int l[]){
//these are the indexes
int first, last, splitPoint;
Stack stack = new Stack();
stack.push(0);
last = l.length-1;
stack.push(last);
while(!stack.empty())
{
last = (int) stack.pop();
first = (int) stack.pop();
while(first < last){
splitPoint = split2(first, last);
stack.push (splitPoint+1);
stack.push(last);
last = splitPoint - 1;
}
}
}
/**
*
* @param first
* @param last
* @return
*/
private int split2(int first, int last) {
int splitPoint, unknown;
int x;
int temp;
x = l[first];
splitPoint = first;
for (unknown = first + 1; unknown <= last; unknown++) {
if (l[unknown] < x) {
splitPoint = splitPoint + 1;
//interchange(splitPoint, unknown);
temp = l[splitPoint];
l[splitPoint] = l[unknown];
l[unknown] = temp;
}
}
temp = l[first];
l[first] = l[splitPoint];
l[splitPoint] = temp;
return splitPoint;
}
}
迭代快速排序类
public class QuickSort extends SortingAlgorithm {
public QuickSort(int[] l, int pivot) {
super(l);
}
public int[] getL() {
return l;
}
public void quickSort(int first, int last) {
int splitPoint;
if (first < last) {
splitPoint = split(first, last);
quickSort(first, splitPoint - 1);
quickSort(splitPoint + 1, last);
}
}
private int split(int first, int last) {
int splitPoint, unknown;
int x;
int temp;
int temp2;
x = l[first];
splitPoint = first;
for (unknown = first + 1; unknown <= last; unknown++) {
if (l[unknown] < x) {
splitPoint = splitPoint + 1;
//interchange(splitPoint, unknown);
temp = l[splitPoint];
l[splitPoint] = l[unknown];
l[unknown] = temp;
}
}
temp = l[first];
l[first] = l[splitPoint];
l[splitPoint] = temp;
return splitPoint;
}
}
public class QuickSortStack extends SortingAlgorithm {
public QuickSortStack(int[] l) {
super(l);
}
public int[] getL() {
return l;
}
/**
*
* @param l
*/
public void explicitStackingQuicksortCustomPivot(int l[]){
//these are the indexes
int first, last, splitPoint;
Stack stack = new Stack();
stack.push(0);
last = l.length-1;
stack.push(last);
while(!stack.empty())
{
last = (int) stack.pop();
first = (int) stack.pop();
while(first < last){
splitPoint = split2(first, last);
stack.push (splitPoint+1);
stack.push(last);
last = splitPoint - 1;
}
}
}
/**
*
* @param first
* @param last
* @return
*/
private int split2(int first, int last) {
int splitPoint, unknown;
int x;
int temp;
x = l[first];
splitPoint = first;
for (unknown = first + 1; unknown <= last; unknown++) {
if (l[unknown] < x) {
splitPoint = splitPoint + 1;
//interchange(splitPoint, unknown);
temp = l[splitPoint];
l[splitPoint] = l[unknown];
l[unknown] = temp;
}
}
temp = l[first];
l[first] = l[splitPoint];
l[splitPoint] = temp;
return splitPoint;
}
}
公共类QuickSortStack扩展了排序算法{
公共QuickSortStack(int[]l){
超级(l);
}
公共int[]getL(){
返回l;
}
/**
*
*@param l
*/
public void explicitsTackingQuickPortCustomPivot(int l[]){
//这些是索引
int first,last,splitPoint;
堆栈=新堆栈();
堆栈推送(0);
最后=l.长度-1;
栈。推(最后);
而(!stack.empty())
{
last=(int)stack.pop();
first=(int)stack.pop();
while(第一次<最后一次){
splitPoint=split2(第一个,最后一个);
stack.push(拆分点+1);
栈。推(最后);
最后=拆分点-1;
}
}
}
/**
*
*@param-first
*@param last
*@返回
*/
私有整数拆分2(整数优先,整数最后){
int splitPoint,未知;
int x;
内部温度;
x=l[第一];
拆分点=第一个;
对于(未知的=第一+ 1;未知的< P>用java),递归似乎比迭代快一点。这可能是由于堆栈溢出检查在硬件中完成,而索引越界检查是用软件完成的。C++,迭代比递归(没有索引检查)稍微快一些。。注意,对于这些示例,没有代码可以避免堆栈溢出
递归:
public static void qsort(int[] a, int lo, int hi)
{
if(lo >= hi)
return;
int md = lo+(hi-lo)/2;
int ll = lo-1;
int hh = hi+1;
int p = a[md];
int t;
while(true){
while(a[++ll] < p);
while(a[--hh] > p);
if(ll >= hh)
break;
t = a[ll];
a[ll] = a[hh];
a[hh] = t;
}
ll = hh++;
qsort(a, lo, ll);
qsort(a, hh, hi);
}
publicstaticvoidqsort(int[]a,int-lo,int-hi)
{
如果(低>=高)
返回;
int-md=lo+(hi-lo)/2;
int ll=lo-1;
int hh=hi+1;
int p=a[md];
int t;
while(true){
而(a[++ll]p);
如果(ll>=hh)
打破
t=a[ll];
a[ll]=a[hh];
a[hh]=t;
}
ll=hh++;
qsort(a、lo、ll);
qsort(a,hh,hi);
}
迭代:
public static void qsort(int[] a)
{
int[] stk = new int[65536]; // stack
int sti = 0; // stack index
stk[sti++] = a.length-1;
stk[sti++] = 0;
while(sti != 0){
int lo = stk[--sti];
int hi = stk[--sti];
if(lo >= hi)
continue;
int md = lo+(hi-lo)/2;
int ll = lo-1;
int hh = hi+1;
int p = a[md];
int t;
while(true){
while(a[++ll] < p);
while(a[--hh] > p);
if(ll >= hh)
break;
t = a[ll];
a[ll] = a[hh];
a[hh] = t;
}
ll = hh++;
stk[sti++] = hi;
stk[sti++] = hh;
stk[sti++] = ll;
stk[sti++] = lo;
}
}
publicstaticvoidqsort(int[]a)
{
int[]stk=newint[65536];//堆栈
int sti=0;//堆栈索引
stk[sti++]=a.length-1;
stk[sti++]=0;
while(sti!=0){
int-lo=stk[--sti];
inthi=stk[--sti];
如果(低>=高)
继续;
int-md=lo+(hi-lo)/2;
int ll=lo-1;
int hh=hi+1;
int p=a[md];
int t;
while(true){
而(a[++ll]p);
如果(ll>=hh)
打破
t=a[ll];
a[ll]=a[hh];
a[hh]=t;
}
ll=hh++;
stk[sti++]=hi;
stk[sti++]=hh;
stk[sti++]=ll;
stk[sti++]=lo;
}
}
这似乎是一种Java基准测试,而不是快速排序;请参阅,例如,Stack
既旧又慢。尝试使用ArrayDeque
而不是Qucksort。两者都不是Qucksort。更像是递归冒泡排序或shell排序。比较下面的答案,这是一种快速排序。完全不同。您的测量方法是有缺陷。你主要是在测量副作用,而不是你的实际代码。这使得你的基准测试毫无用处。请阅读如何正确使用Java进行微基准测试(使用JMH)。