Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 递归快速排序比迭代快速排序更快_Java_Sorting_Recursion_Quicksort - Fatal编程技术网

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)。