Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/130.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.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
C++ 快速排序&x27;排序降序和升序数据时的奇怪行为_C++_Algorithm_Sorting - Fatal编程技术网

C++ 快速排序&x27;排序降序和升序数据时的奇怪行为

C++ 快速排序&x27;排序降序和升序数据时的奇怪行为,c++,algorithm,sorting,C++,Algorithm,Sorting,当以降序-升序(100,99,…,0,99,100)对包含数字的数组进行排序时,为什么qs的这种实现工作如下: 对于700000个元素,它的工作速度比650000个元素快。我重复了几次测试。 代码如下: #include <iostream> #include <cstdlib> #include <time.h> #include <new> #include <math.h> usi

当以降序-升序(100,99,…,0,99,100)对包含数字的数组进行排序时,为什么qs的这种实现工作如下:

对于700000个元素,它的工作速度比650000个元素快。我重复了几次测试。 代码如下:

    #include <iostream>
    #include <cstdlib>
    #include <time.h>
    #include <new>
    #include <math.h>

    using namespace std;
    inline void swap (int *a, int *b)
    {
        int tmp;
        tmp = *a;
        *a = *b;
        *b = tmp;
    }
    void quick_sort(int tab[], int l, int r);
    int *allocate (int size);
    void dec_inc (int tab[], const int length);
    int main()
    {
        int step = 50000;
        int how_many = 15;
        int k = 1;
        int length = step * how_many;
        int *tab = allocate(length);
        clock_t t2, t1;
        long double dif;
        while (step * k <= length)
        {
            dec_inc(tab, step*k);
            t1 = clock();
            quick_sort(tab, 0, step*k - 1);
            t2 = clock();
            dif = (long double)(t2 - t1)/CLOCKS_PER_SEC;
            cout << "time for " << step * k << " elements: " << dif << " s" << endl;
            k++;
        }
        delete [] tab;
        system("pause");

    }
    int *allocate (int size)
    {
        try
        {
            return new int [size];
        }
        catch(bad_alloc)
        {
            cerr << "ERROR\n";
            exit(EXIT_FAILURE);
        }
    }
    void quick_sort(int tab[], int l, int r)
    {
        int v = tab[(l+r)/2];
        int i = l;
        int j = r;
        do
        {
            while(tab[i] < v) i++;
            while(tab[j] > v) j--;
            if (i <= j)
            {
                swap(&tab[i], &tab[j]);
                i++, j--;
            }
        }
        while(i <= j);
        if (l < j)
            quick_sort(tab, l, j);
        if(i < r)
            quick_sort(tab, i, r);
    }
    void dec_inc (int tab[], const int length)
    {
        int i = length/2;
        for (int j = 0; j < length/2; j++, i--)
        {
            tab[j] = i;
        }
        for (int j = length/2; j < length; j++, i++)
        {
            tab[j] = i;
        }
    }
#包括
#包括
#包括
#包括
#包括
使用名称空间std;
内联无效交换(int*a,int*b)
{
int tmp;
tmp=*a;
*a=*b;
*b=tmp;
}
无效快速排序(int tab[],int l,int r);
int*分配(int大小);
void dec_inc(int tab[],常数int length);
int main()
{
int步长=50000;
int多少=15;
int k=1;
整数长度=步长*多少;
int*tab=分配(长度);
时钟t2,t1;
长双dif;

而(步骤*k使用快速排序的缺点之一是它的稳定性。某些数据集需要比其他数据集更多的步骤进行排序。对于病理病例,它甚至可以扩展为O(n^2)。我测量了quicksort对您的测试数据执行的比较次数,发现在700000个步骤中,要执行的比较少于650000个元素。尽管您的数据集看起来相似,但显然对于quicksort,它们并不相似。有一些方法可以提高quicksort的稳定性,例如,请参阅

以下是测量结果:

650000个元素的时间:4.41251 s.数量比较5061169826

700000个元素的时间:3.37787 s.数量比较3824058435

750000个元素的时间:6.07856秒数比较6900645055


这里是相应的代码:

使用快速排序的缺点之一是它的稳定性。某些数据集需要比其他数据集更多的步骤进行排序。对于病理病例,它甚至可以扩展为O(n^2)。我测量了quicksort对您的测试数据执行的比较次数,发现在700000个步骤中,要执行的比较少于650000个元素。尽管您的数据集看起来相似,但显然对于quicksort,它们并不相似。有一些方法可以提高quicksort的稳定性,例如,请参阅

以下是测量结果:

650000个元素的时间:4.41251 s.数量比较5061169826

700000个元素的时间:3.37787 s.数量比较3824058435

750000个元素的时间:6.07856秒数比较6900645055



这里是相应的代码:

您是否多次运行此程序,以查看它是否不是数据中的一个光点。也就是说,其他进程已停止,因此在执行该部分时有更多可用的系统资源。我多次运行此程序。出现了类似的偏差。您是否可以共享生成此输出的完整代码,以便我可以运行它?Th几乎可以肯定的是与缓存和/或虚拟内存有关。您可以插入代码以计算调用
quick_sort
函数和
swap
函数的次数,并且没有任何意外情况发生。计数增加
n log(n)
随着数组长度的增加。CPU内部有很多奇怪的效果。例如分支预测。那些while循环将在总是为真到总是为假的预测之间切换。当预测值正确时,运行速度会更快。当预测错误时,您将得到一系列管道stalls.您是否多次运行此操作以查看它是否是数据中的一个光点。例如,其他进程已停止,因此该部分执行中有更多可用的系统资源。我多次运行此操作。出现类似的偏差。您是否可以共享生成此输出的完整代码,以便我可以运行它?这几乎肯定与ca有关清零和/或虚拟内存。您可以插入代码以计算调用
quick_sort
函数和
swap
函数的次数,并且不会发生意外情况。计数会增加
n log(n)
随着数组长度的增加。CPU内部有很多奇怪的效果。例如分支预测。那些while循环将在总是为真到总是为假的预测之间切换。当预测值正确时,运行速度会更快。当预测错误时,您将得到一系列管道stalls.您的代码溢出了int!您的结果不正确。哦,nvm在您的编译器long=long long中看起来很像,在我的编译器中,它的long=int so+1感谢您指出了这个溢出问题。相应地更改了代码。@pbarmettler“尽管您的数据集看起来很相似,但对于快速排序,它们显然不是。”但是为什么?轴心点总是0,那么为什么比较的数量在减少?我不明白在你的例子中轴心点怎么总是0。如果你期望你的快速排序算法应该以某种方式运行,那么在每一步后使用小例子分析输出可能会很有用。有趣的是,在你的例子中,轴心点的下降会导致mparison计数也会发生在非常小的向量上,例如大小10和大小14。您可能会从这些情况中学到一些东西。您的代码溢出int!您的结果不正确。哦,nvm在您的编译器中看起来像long=long long,在我的编译器中它的long=int so+1感谢您指出这个溢出问题。相应地更改了代码。@pbarmettler“尽管您的数据集看起来很相似,但显然对于快速排序来说,它们并不相似。"但是为什么?轴心点总是0,那么为什么比较的数量在减少?我不明白在你的例子中轴心点怎么总是0。如果你期望你的快速排序算法应该以某种方式运行,那么在每一步后使用小例子分析输出可能会很有用。有趣的是,在你的例子中,轴心点的下降会导致mparison计数也发生在非常小的向量上,例如大小为10和大小为14。您可以从这些案例中学到一些东西。
    #include <iostream>
    #include <cstdlib>
    #include <time.h>
    #include <new>
    #include <math.h>

    using namespace std;
    inline void swap (int *a, int *b)
    {
        int tmp;
        tmp = *a;
        *a = *b;
        *b = tmp;
    }
    void quick_sort(int tab[], int l, int r);
    int *allocate (int size);
    void dec_inc (int tab[], const int length);
    int main()
    {
        int step = 50000;
        int how_many = 15;
        int k = 1;
        int length = step * how_many;
        int *tab = allocate(length);
        clock_t t2, t1;
        long double dif;
        while (step * k <= length)
        {
            dec_inc(tab, step*k);
            t1 = clock();
            quick_sort(tab, 0, step*k - 1);
            t2 = clock();
            dif = (long double)(t2 - t1)/CLOCKS_PER_SEC;
            cout << "time for " << step * k << " elements: " << dif << " s" << endl;
            k++;
        }
        delete [] tab;
        system("pause");

    }
    int *allocate (int size)
    {
        try
        {
            return new int [size];
        }
        catch(bad_alloc)
        {
            cerr << "ERROR\n";
            exit(EXIT_FAILURE);
        }
    }
    void quick_sort(int tab[], int l, int r)
    {
        int v = tab[(l+r)/2];
        int i = l;
        int j = r;
        do
        {
            while(tab[i] < v) i++;
            while(tab[j] > v) j--;
            if (i <= j)
            {
                swap(&tab[i], &tab[j]);
                i++, j--;
            }
        }
        while(i <= j);
        if (l < j)
            quick_sort(tab, l, j);
        if(i < r)
            quick_sort(tab, i, r);
    }
    void dec_inc (int tab[], const int length)
    {
        int i = length/2;
        for (int j = 0; j < length/2; j++, i--)
        {
            tab[j] = i;
        }
        for (int j = length/2; j < length; j++, i++)
        {
            tab[j] = i;
        }
    }