2009-11-01 138 views
1

我想傳遞一個任意的結構指針數組和比較函數到一個通用的排序算法。這可能在C嗎?將任意結構指針的數組傳遞給C函數?

只能在比較函數內訪問結構的陰影,排序函數只需要調用比較函數和交換指針,但我不知道如何聲明它。

function sorter(struct arbitrary ** Array, int Length, int cmp(struct node * a, struct node * b)) 
{ 
    for (int i=0; i<Length;i++){ 
     if cmp(Array[i],Array[i+1]){ 
      swap(Array[i],Array[i+1] 
     } 
    } 
} 
+0

注意**緩衝區溢出**。在你的代碼中,通過循環的最後一遍,'i + 1'將嘗試訪問一個不可知的元素。 – pmg 2009-11-01 11:55:55

回答

3

你可以聲明功能:

void sorter(void** the_array, size_t array_length, int (*comparison_function)(void*, void*)); 

裏面的比較函數,您將需要轉換的兩個指針被比指向任何結構類型的比較功能進行比較。

+0

你的意思是「你*不*必須去掉指針」,是嗎?但OP似乎已經知道了。 – AnT 2009-11-01 05:37:49

+0

謝謝,我不知道我可以使用那樣的void指針。 – ABentSpoon 2009-11-01 05:41:22

+0

@AndreyT:當我在StackOverflow上遲到時會發生這種情況;對困惑感到抱歉。 @ABentSpoon:不客氣。 – 2009-11-01 05:45:10

0

也許你只需要傳遞void指針?

function sorter(void ** Array, int Length, int cmp(void * a, void * b)) 
0

因爲您可以將每個指針轉換爲void*,所以在C中總是有可能。但是,如果您希望能夠將其轉換爲指向任意結構的指針,則需要某種類型的標識。

您可以通過使用特定於該類型的函數(如果您比較的內容相同)或者以某種方式將該類型編碼到結構中來實現。這可以通過在結構中增加一個字段來完成,或者通過改變cmp()函數本身來獲取類型標識符。

但是你應該知道,C處已經有一個qsort()功能,這通常是相當有效的(雖然沒有什麼在決定哪種算法,它使用了標準的 - 它可能使用冒泡排序,仍然是符合)。除非你正在實現一個功課,或者有一個不同的算法,頭部應該可以使用它。

你的算法,就像它的樣子,看起來像一個冒泡排序的內部循環,因此,實際上不會正確排序。 Bubble排序由兩個嵌套循環組成,通常只適用於小數據集或具有特定特徵的那些數據集(例如大多數已排序)。

1

其實這個功能已經存在了...它叫做qsort。查看一些文檔here。它比你的實現更有效率,它是O(n^2)。

+0

實際上,那個實現是O(n)對於排序例程來說非常好,除了它不排序的事實:-) – paxdiablo 2009-11-01 05:45:49

+0

實際上,我的是O(n),但它只排序幾乎排序的數組:)。但是,謝謝。我一定會利用這一點。 – ABentSpoon 2009-11-01 05:48:14

+0

對於幾乎有序數組的情況,libc通常也有mergesort()。不過記住它比qsort消耗更多的內存。 – alecco 2009-11-01 07:11:28