Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/142.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++ 比较排序和各种排序算法的潜在溢出_C++ - Fatal编程技术网

C++ 比较排序和各种排序算法的潜在溢出

C++ 比较排序和各种排序算法的潜在溢出,c++,C++,我目前正在使用一个简单的程序,该程序比较许多常用排序方法的比较和交换数量,并在大小为1000、2000、5000、10000、50000和100000的数据集上进行测试。在50000个值之前,该程序似乎工作正常。但是,例如,在50000个值处使用随机值测试插入方法,得出的比较计数为626936785,而在100000个值处,输出为-1788822792。我已经包含了下面的完整代码,随着交换和比较数量的增长,是否有可能出现某种溢出,无法正确跟踪 #include <cstdlib> #

我目前正在使用一个简单的程序,该程序比较许多常用排序方法的比较和交换数量,并在大小为1000、2000、5000、10000、50000和100000的数据集上进行测试。在50000个值之前,该程序似乎工作正常。但是,例如,在50000个值处使用随机值测试插入方法,得出的比较计数为626936785,而在100000个值处,输出为-1788822792。我已经包含了下面的完整代码,随着交换和比较数量的增长,是否有可能出现某种溢出,无法正确跟踪

#include <cstdlib>
#include <getopt.h>
#include <iostream>
#include <string>

using namespace std;
long long comparisons;
long long swaps;

bool comp_less(int a, int b){
    ++comparisons;
    return a < b;
}

void swap(int& a, int& b)
{
    ++swaps;
    int t = a;
    a = b;
    b = t;
}

void selectionSort(int *first, int *last)
{

    for(int *i = first; i < (last - 1); ++i){
        int *min = i;
        for(int *j = i + 1; j < last; ++j){
            if(comp_less(*j, *min)){
                min = j;
            }
        }
        swap(*i, *min);
    }

}


void insertionSort(int* first, int* last)
{
    for (int *i = first + 1; i < last; ++i)
    {
        int temp = *i;
        int *j;
        for (j = i; j > first && comp_less(temp, *(j - 1)); --j)
        {
            swap(*j, *(j - 1));
        }
        *j = temp;
    }
}
int *partition(int *first, int *last)
{

    int *pivot = last - 1;
    int *i = first;
    int *j = last - 1;
    for (;;)
    {
        while (comp_less(*i, *pivot) && i < last)
        {
            ++i;
        }
        while (*j >= *pivot && j > first)
        {
            --j;
        }
        if (i >= j)
            break;

        swap(*i, *j);
    }
    swap(*(last - 1), *i);
    return i;
}

void quickSort(int* first, int* last) {
    {
        if ((first - last) <= 1)
            return;
        int *pivot = partition(first, last);

        quickSort(first, pivot);
        quickSort(pivot + 1, last);
    }
}

int main(int argc, char** argv)
{
    string algorithm = "selection";
    string dataset = "random";

    for (int c; (c = getopt(argc, argv, "ravqsin")) != -1;) {
        switch (c) {
            case 'r':
                dataset = "random";
                break;
            case 'a':
                dataset = "sorted";
                break;
            case 'v':
                dataset = "reverse";
                break;
            case 'q':
                algorithm = "quicksort";
                break;
            case 's':
                algorithm = "selection";
                break;
            case 'i':
                algorithm = "insertion";
                break;
            case 'n':
                algorithm = "none";
                break;
        }
    }
    argc -= optind;
    argv += optind;

    const int size = argc > 0 ? atoi(argv[0]) : 10000;
    int* data = new int[size];

    if (dataset == "sorted") {
        for (int i = 0; i < size; ++i) {
            data[i] = i;
        }
    }
    else if (dataset == "reverse") {
        for (int i = 0; i < size; ++i) {
            data[i] = size - i - 1;
        }
    }
    else if (dataset == "random") {
        for (int i = 0; i < size; ++i) {
            data[i] = rand() % size;
        }
    }

    if (algorithm == "quicksort") {
        quickSort(data, data + size);
    }
    else if (algorithm == "selection") {
        selectionSort(data, data + size);
    }
    else if (algorithm == "insertion") {
        insertionSort(data, data + size);
    }
    else if (algorithm=="none"){
        cout<< "Oops!" <<'\n';
        exit(1);
    }

    cout << "OK" << '\n';
    cout << "Algorithm:   " << algorithm << '\n';
    cout << "Data set:    " << dataset << '\n';
    cout << "Size:        " << size << '\n';
    cout << "Comparisons: " << comparisons << '\n';
    cout << "Swaps:       " << swaps << '\n';
    return 0;
}
#包括
#包括
#包括
#包括
使用名称空间std;
长期比较;
长期掉期;
布尔补偿(内部a、内部b){
++比较;
返回afirst&comp__(temp,*(j-1));--j)
{
互换(*j,*(j-1));
}
*j=温度;
}
}
int*分区(int*第一,int*最后)
{
int*pivot=last-1;
int*i=第一;
int*j=last-1;
对于(;;)
{
而(比较少(*i,*pivot)和&i=*轴和&j>第一个)
{
--j;
}
如果(i>=j)
打破
互换(*i,*j);
}
掉期(*(最后-1),*i);
返回i;
}
无效快速排序(int*first,int*last){
{
如果((第一个-最后一个)0?原子(argv[0]):10000;
整数*数据=新整数[大小];
如果(数据集==“排序”){
对于(int i=0;i
#include <cstdlib>
#include <getopt.h>
#include <iostream>
#include <string>

using namespace std;
long long comparisons;
long long swaps;

bool comp_less(int a, int b){
    ++comparisons;
    return a < b;
}

void swap(int& a, int& b)
{
    ++swaps;
    int t = a;
    a = b;
    b = t;
}

void selectionSort(int *first, int *last)
{

    for(int *i = first; i < (last - 1); ++i){
        int *min = i;
        for(int *j = i + 1; j < last; ++j){
            if(comp_less(*j, *min)){
                min = j;
            }
        }
        swap(*i, *min);
    }

}


void insertionSort(int* first, int* last)
{
    for (int *i = first + 1; i < last; ++i)
    {
        int temp = *i;
        int *j;
        for (j = i; j > first && comp_less(temp, *(j - 1)); --j)
        {
            swap(*j, *(j - 1));
        }
        *j = temp;
    }
}
int *partition(int *first, int *last)
{

    int *pivot = last - 1;
    int *i = first;
    int *j = last - 1;
    for (;;)
    {
        while (comp_less(*i, *pivot) && i < last)
        {
            ++i;
        }
        while (*j >= *pivot && j > first)
        {
            --j;
        }
        if (i >= j)
            break;

        swap(*i, *j);
    }
    swap(*(last - 1), *i);
    return i;
}

void quickSort(int* first, int* last) {
    {
        if ((first - last) <= 1)
            return;
        int *pivot = partition(first, last);

        quickSort(first, pivot);
        quickSort(pivot + 1, last);
    }
}

int main(int argc, char** argv)
{
    string algorithm = "selection";
    string dataset = "random";

    for (int c; (c = getopt(argc, argv, "ravqsin")) != -1;) {
        switch (c) {
            case 'r':
                dataset = "random";
                break;
            case 'a':
                dataset = "sorted";
                break;
            case 'v':
                dataset = "reverse";
                break;
            case 'q':
                algorithm = "quicksort";
                break;
            case 's':
                algorithm = "selection";
                break;
            case 'i':
                algorithm = "insertion";
                break;
            case 'n':
                algorithm = "none";
                break;
        }
    }
    argc -= optind;
    argv += optind;

    const int size = argc > 0 ? atoi(argv[0]) : 10000;
    int* data = new int[size];

    if (dataset == "sorted") {
        for (int i = 0; i < size; ++i) {
            data[i] = i;
        }
    }
    else if (dataset == "reverse") {
        for (int i = 0; i < size; ++i) {
            data[i] = size - i - 1;
        }
    }
    else if (dataset == "random") {
        for (int i = 0; i < size; ++i) {
            data[i] = rand() % size;
        }
    }

    if (algorithm == "quicksort") {
        quickSort(data, data + size);
    }
    else if (algorithm == "selection") {
        selectionSort(data, data + size);
    }
    else if (algorithm == "insertion") {
        insertionSort(data, data + size);
    }
    else if (algorithm=="none"){
        cout<< "Oops!" <<'\n';
        exit(1);
    }

    cout << "OK" << '\n';
    cout << "Algorithm:   " << algorithm << '\n';
    cout << "Data set:    " << dataset << '\n';
    cout << "Size:        " << size << '\n';
    cout << "Comparisons: " << comparisons << '\n';
    cout << "Swaps:       " << swaps << '\n';
    return 0;
}
输出似乎表明正在发生溢出

您可以添加一个测试来确保

void swap(int& a, int& b)
{
    ++swaps;

    if ( swaps == std::numeric_limits<decltype(swaps)>::max() )
    {
        std::cout << "Number of swaps reached max value. Resetting it 0.\n";
        swaps = 0;
    }

    int t = a;
    a = b;
    b = t;
}

您正在测试哪种算法?旁白:在
分区中
您在第一个内部循环中调用
comp_less
,但在第二个内部循环中执行直接比较。对于
快速排序
@TonyTannous,比较将被低估,最初只需使用排序、反向排序和随机排序的值插入排序即可。该函数显示为brea所有情况下的k值均为100000however@500-InternalServerError感谢您的关注谢谢,我添加了您的测试,但是似乎没有达到最大值,这是有意义的,因为即使有100000个变量,long-long类型也不应该达到最大值。编辑:将该类型更改为未签名的long-long似乎已经修复了我的问题e、 为什么这会延迟达到最大值?@NicholasFischer,
无符号长
可以保持的最大值是
可以保持的最大值的两倍。