稳定标准库 qsort?
我假设 stdlib 中的旧 qsort 函数不稳定,因为手册页没有提及任何相关内容。 这就是我正在谈论的函数:
#include <stdlib.h>
void qsort(void *base, size_t nmemb, size_t size,
int(*compar)(const void *, const void *));
我假设如果我将比较函数更改为也包括我正在比较的地址,它将是稳定的。 那是对的吗?
例如:
int compareFoos( const void* pA, const void *pB ) {
Foo *pFooA = (Foo*) pA;
Foo *pFooB = (Foo*) pB;
if( pFooA->id < pFooB->id ) {
return -1;
} else if( pFooA->id > pFooB->id ) {
return 1;
} else if( pA < pB ) {
return -1;
} else if( pB > pA ) {
return 1;
} else {
return 0;
}
}
I'm assuming that the good old qsort function in stdlib is not stable, because the man page doesn't say anything about it. This is the function I'm talking about:
#include <stdlib.h>
void qsort(void *base, size_t nmemb, size_t size,
int(*compar)(const void *, const void *));
I assume that if I change my comparison function to also include the address of that which I'm comparing, it will be stable. Is that correct?
Eg:
int compareFoos( const void* pA, const void *pB ) {
Foo *pFooA = (Foo*) pA;
Foo *pFooB = (Foo*) pB;
if( pFooA->id < pFooB->id ) {
return -1;
} else if( pFooA->id > pFooB->id ) {
return 1;
} else if( pA < pB ) {
return -1;
} else if( pB > pA ) {
return 1;
} else {
return 0;
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
不,不幸的是你不能依赖这一点。 假设您有一个数组(每条记录中有两个字段用于检查,但只有第一个字段用于排序):
不稳定排序可能会将
B,1
与A,3
进行比较code> 并交换它们,给出:如果下一步是将
B,2
与B,1
进行比较,则密钥将是相同的,并且,因为B ,2
的地址小于B,1
,不会发生交换。 对于稳定的排序,您应该得到以下结果:唯一的方法是附加指针的起始地址(而不是其当前地址)并排序使用该键以及其他键。 这样,原始地址就成为排序键的次要部分,因此无论两个
B 在哪里,
行在排序过程中进行。B,1
最终都会排在B,2
之前。No, you cannot rely on that unfortunately. Let's assume you have the array (two fields in each record used for checking but only first field used for sorting):
A non-stable sort may compare
B,1
withA,3
and swap them, giving:If the next step were to compare
B,2
withB,1
, the keys would be the same and, sinceB,2
has an address less thanB,1
, no swap will take place. For a stable sort, you should have ended up with:The only way to do it would be to attach the starting address of the pointer (not its current address) and sort using that as well as the other keys. That way, the original address becomes the minor part of the sort key so that
B,1
will eventually end up beforeB,2
regardless of where the twoB
lines go during the sorting process.规范的解决方案是创建(即分配内存并填充)指向原始数组元素的指针数组,并使用额外的间接级别进行 qsort 这个新数组并回退到比较当指针所指向的事物相等时,指针值。 这种方法具有潜在的副作用,即您根本不修改原始数组 - 但如果您希望原始数组最终排序,则必须对其进行排列以匹配之后指针数组中的顺序
qsort
返回。The canonical solution is to make (i.e. allocate memory for and fill) an array of pointers to the elements of the original array, and
qsort
this new array, using an extra level of indirection and falling back to comparing pointer values when the things they point to are equal. This approach has the potential side benefit that you don't modify the original array at all - but if you want the original array to be sorted in the end, you'll have to permute it to match the order in the array of pointers afterqsort
returns.这不起作用,因为在排序过程中,排序会发生变化,并且两个元素将不会有一致的输出。 为了使老式的 qsort 稳定,我所做的就是在我的结构中添加初始索引,并在将其传递给 qsort 之前初始化该值。
This does not work because during the sort procedure, the ordering will change and two elements will not have consistent output. What I do to make good old-fashioned qsort stable is to add the initial index inside my struct and initialize that value before passing it to qsort.