qsort 要注意的问题
2007-09-04 23:23 老博客哈 阅读(1619) 评论(4) 编辑 收藏 举报
大家竞相转载的 《qsort的七种排序》里面有不少细节问题,由于原版不知道是哪里的,所以部分错误可能是转载人漏掉或者误添的,这个暂且不谈,不过今天在hnu的论坛上看见yiyi的回复才知道原来最大的问题是出在作者的cmp函数里面:
int cmp ( const void *a , const void *b )
{
return *(int *)a - *(int *)b;
}
这个问题出在 当a是int的最大值(2^31 - 1),b是int的最小值(-2^31)时,a - b会溢出,返回了一个正数,言下之意就是说a < b了,这显然是错误的了。(赞一下yiyi,估计srm 中cha人cha的比较多了)
这个问题比较好的解决方法是采用比较,而不是这种看似很有“技巧”的写法或者使用STL中的std::sort
下面给出测试代码,希望大家少犯错误:-)
#include <cstdlib>
#include <algorithm>
#include <iostream>
![](/Images/OutliningIndicators/None.gif)
using namespace std;
![](/Images/OutliningIndicators/None.gif)
int cmp(const void* a, const void * b)
{
return *(int *)a - *(int *)b;
}
![](/Images/OutliningIndicators/None.gif)
int cmp2(const void *a, const void *b)
{
int aa = *(int *)a;
int bb = *(int *)b;
![](/Images/OutliningIndicators/InBlock.gif)
if(aa == bb)
return 0;
else if(aa < bb)
return -1;
else
return 1;
}
![](/Images/OutliningIndicators/None.gif)
bool cmp3(const int a, const int b)
{
return a < b;
}
![](/Images/OutliningIndicators/None.gif)
int main()
{
int a[] = {-0x7fffffff - 1, 0x7fffffff};
qsort(a, 2, sizeof(a[0]), cmp);
cout << a[0] << " " << a[1] << endl;
![](/Images/OutliningIndicators/InBlock.gif)
int b[] = {-0x7fffffff - 1, 0x7fffffff};
qsort(b, 2, sizeof(b[0]), cmp2);
cout << b[0] << " " << b[1] << endl;
![](/Images/OutliningIndicators/InBlock.gif)
int c[] = {-0x7fffffff - 1, 0x7fffffff};
sort(c, c + 2, cmp3);
cout << c[0] << " " << c[1] << endl;
![](/Images/OutliningIndicators/InBlock.gif)
return 0;
}
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
这个问题出在 当a是int的最大值(2^31 - 1),b是int的最小值(-2^31)时,a - b会溢出,返回了一个正数,言下之意就是说a < b了,这显然是错误的了。(赞一下yiyi,估计srm 中cha人cha的比较多了)
这个问题比较好的解决方法是采用比较,而不是这种看似很有“技巧”的写法或者使用STL中的std::sort
下面给出测试代码,希望大家少犯错误:-)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedBlockEnd.gif)