2012-11-30 61 views
1

我一直在尋找一種在C中對數組的子集進行排序的方法,而無需將元素移動到臨時數組,然後將其複製回來。我可能對qsort有一個不好理解,但我認爲下面的代碼應該可以工作:在數組的子集上調用qsort

qsort(&my_struct_arr[1],3,sizeof(my_struct),my_struct_cmp); 
//my_struct_arr is a 4 element array, where i want to sort from position 1 to 3 
int my_struct_cmp(const void *a, const void *b) 
{ 
    my_struct A=*(my_struct*)a, B=*(my_struct*)b; 
    if(A.x-B.x < 0.01) return A.y-B.y; 
    return A.x-B.x; 
} 
typedef struct foo 
{ 
    float x, y; 
} my_struct; 

問題是,它不起作用。

更新1: 好的,我看到我並不完全清楚這個問題。我將陣列從位置1初始化爲3,所以我有一個這樣的元素的陣列:

{{ValueFromPreviousIteration.x,ValueFromPreviousIteration.y},{x1,y1},{x2,y2},{x3, Y3}}

我的問題是,快速排序稱爲像上面將整個數組排序,而我只希望它的最後3個元素進行排序。

+0

您可以更加清楚通過張貼小,完整的,可編譯演示該問題例如這個問題。您所發佈的內容中的'qsort()'調用看起來應該做你想做的事情(雖然比較函數有幾個答案中描述的問題)。所以如果問題不是比較,那麼這可能是你沒有向我們展示過的東西。 –

回答

0

int my_struct_cmp返回int。

你正在返回float。它會自動轉換爲int,並且可能爲0

這就是爲什麼它不起作用。

0

if(A.x-B.x < 0.01)是否正確?你可能想要if(A.x-B.x < 0.0)。使用0.0代替0.01

+0

我正在做一個opengl程序,其中x和y代表座標。在屏幕上,x的差異爲0.01並沒有實際的區別。 – VSZM

1

您的比較函數不穩定。它可以根據結構傳遞的順序返回不同的結果。

考慮以下結構值:

my_struct m = { -3.021, 30 }; 
my_struct n = { 3.010, 0 };  

int main(void) 
{ 
    int comp1 = my_struct_cmp(&m, &n); 
    int comp2 = my_struct_cmp(&n, &m); 

    printf("%d %d\n", comp1, comp2); 

    return 0; 
} 

第一比較指示m > n,而第二個指示n > m。這種行爲混淆了qsort()

+0

因此,調用'fabs()'缺失。 **此外,它會截斷差異,所以如果其絕對值小於1,它將錯誤地返回0而不是「+/- 1」。 – 2013-10-10 19:23:01

0

我想你需要修改比較功能,以類似

int my_struct_cmp(const void* a, const void* b) 
{ 
    const my_struct A = *(my_struct*)a, B = *(my_struct*)b; 
    return fabs(A.x - B.x) >= 0.01 ? (A.x > B.x) - (A.x < B.x) : (A.y > B.y) - (A.y < B.y); 
} 

或(不那麼便攜式)

int my_struct_cmp(const void* a, const void* b) 
{ 
    const my_struct A = *(my_struct*)a, B = *(my_struct*)b; 
    return fabs(A.x - B.x) >= 0.01 ? copysign(1, A.x - B.x) : copysign(1, A.y - B.y); 
} 

否則,存在許多特定於平臺的解決方案確定的標誌實際上浮動而不進行比較,這實際上不是一件微不足道的事情。

,這應該是快了一點:

int my_struct_cmp(const void* a, const void* b) 
{ 
    const my_struct *A = (my_struct*)a, *B = (my_struct*)b; 
    return fabs(A->x - B->x) >= 0.01 ? (A->x > B->x) - (A->x < B->x) : (A->y > B->y) - (A->y < B->y); 
}