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