题
我假设在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;
}
}
解决方案
没有,你不能依赖于不幸。让我们假设你有阵列(在每个记录中的两个字段用于检查,但用于排序仅第一个字段):
BBBB,1
BBBB,2
AAAA,3
快速排序可以比较BBBB,1 AAAA,3和交换它们,得到:
AAAA,3
BBBB,2
BBBB,1
如果下一个步骤是比较BBBB,2 BBBB,如图1所示,键将是相同的,并且由于BBBB,2具有的地址小于BBBB,1,没有交换将发生。对于一个稳定的排序,你应该已经结束了:
AAAA,3
BBBB,1
BBBB,2
这样做将是附加的起始的指针的地址(而不是它的电流的地址)和排序使用以及其他键的唯一方法。这样一来,原来的地址变成了排序键的小部分,这样BBBB,1
终将BBBB,2
前结束了,无论在分拣过程中两个BBBB
线去的地方。
其他提示
在典型的解决方案是让(即,对于分配内存和填充)指向原始阵列的元件的阵列,并且qsort
这个新的数组,使用额外的间接水平和回落至比较指针值当它们指向的事情是相等的。此方法具有不修改原始数组在所有可能的附带好处 - 但如果你想原始数组到底进行排序,你就必须要置换它的顺序指针后阵列中的匹配qsort
回报。
这不排序过程中,因为工作,排序会改变,两个元素不会有一致的输出。我做才能让老式的qsort稳定是通过它来快速排序之前增加初始索引我的结构内和初始化值。
typedef struct __bundle {
data_t some_data;
int sort_score;
size_t init_idx;
} bundle_t;
/*
.
.
.
.
*/
int bundle_cmp(void *ptr1, void *ptr2) {
bundle_t *b1, *b2;
b1 = (budnel_t *) ptr1;
b2 = (budnel_t *) ptr2;
if (b1->sort_score < b2->sort_score) {
return -1;
}
if (b1->sort_score > b2->sort_score) {
return 1;
}
if (b1->init_idx < b2->init_idx) {
return -1;
}
if (b1->init_idx > b2->init_idx) {
return 1;
}
return 0;
}
void sort_bundle_arr(bundle_t *b, size_t sz) {
size_t i;
for (i = 0; i < sz; i++) {
b[i]->init_idx = i;
}
qsort(b, sz, sizeof(bundle_t), bundle_cmp);
}
不隶属于 StackOverflow