我假设在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);
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top