簡體   English   中英

通過在 C 中使用 qsort function 對數據結構進行排序來解決問題

[英]problem by ordering a data structure using the qsort function in C

我需要訂購一個數據結構數組,其中包含與節點來源、目的地和權重相關的信息。 問題沒有正確排序,因為如果兩個值等於 array.originNode 只是取你得到的第一個值而不是應該排序的值。

這就是我的代碼對結構進行排序的方式

0 1 30
1 3 22
2 3 20
3 5 20
3 4 15

Process returned 0 (0x0)   execution time : 0.015 s

這是它應該如何訂購

0 1 30
1 3 22
2 3 20
3 4 15
3 5 20

我認為問題是我作為參數傳遞給 qsort 的 function ,它沒有進行正確的比較。 如何將我的比較 function 更改為我的代碼正確排序結構數組?

這是我的完整代碼

#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <unistd.h>

 typedef struct dataNodes{
   int originNode;
   int destinationNode;
   int weight;
   struct dataNodes *next;
} ARRAYS;


  int function (const void * a, const void * b)
{
  return ( *(int*)a - *(int*)b );
}


int main() {
ARRAYS array[6];
int n = 5, i;

array [0].originNode = 3;
array [1].originNode = 3;
array[2].originNode = 1;
array[3].originNode = 0;
array[4].originNode = 2;


array [0].destinationNode = 4 ;
array [1].destinationNode = 5;
array[2].destinationNode = 3;
array[3].destinationNode = 1;
array[4].destinationNode = 3;


array [0].weight = 15;
array [1].weight = 20;
array[2].weight = 22;
array[3].weight = 30;
array[4].weight = 20;


              qsort(array,n,sizeof(array[0]),function);
    for(i=0; i<n; i++)
    {
    printf("%d %d %d\n",array[i].originNode,array[i].destinationNode,
    array[i].weight);
    }
return 0;

}

您需要更改比較 function 才能正確比較 ARRAY 記錄。 首先比較originNode,如果它們是相同的比較destinationNode。

int function (const void * a, const void * b)
{
    const ARRAYS *ap = a;
    const ARRAYS *bp = b;
    if( ap->originNode < bp->originNode )
        return -1;
    else if( ap->originNode > bp->originNode )
        return 1;
    else if( ap->destinationNode < bp->destinationNode )
        return -1;
    else if( ap->destinationNode > bp->destinationNode )
        return 1;
    else
        return 0;
 }

您正在對 (uh...) ARRAYS的數組進行排序。 因此,您傳入的排序 function 應該是比較ARRAYS對象。 您的代碼將其視為int

做二次排序,需要在主字段相等的情況下,比較對應的次字段。 對要比較的更多字段執行相同操作。

所以在你的情況下,這種 function 可以為你工作:

int sort_ARRAYS (const void * a, const void * b)
{
    /* the arguments are pointers to ARRAYS objects */
    const ARRAYS *x = a;
    const ARRAYS *y = b;
    int cmp;

    /* primary */
    cmp = x->originNode - y->originNode;
    if (cmp != 0) return cmp;

    /* secondary */
    cmp = x->destinationNode - y->destinationNode;
    if (cmp != 0) return cmp;

    /* tertiary */
    return x->weight - y->weight;
}

來自精美手冊

void qsort(void *base, size_t nel, size_t width, int (*compar)(const void *, const void *));
[...]
compar參數是一個指向比較 function 的指針,它與兩個指向被比較元素的 arguments 一起調用。

因此,您的比較 function 將收到兩個ARRAY * arguments 偽裝成const void *而您的function只需要適當地轉換它們:

int
function(const void * a, const void * b) {
    ARRAYS *aa = (ARRAYS *)a;
    ARRAYS *bb = (ARRAYS *)b;
    return aa->originNode - bb->originNode;
}

如果您想要輔助排序鍵,請檢查是否aa->originNode == bb->originNode並比較輔助鍵是否為真; 如果需要,對於第三鍵也是如此。

您當前的代碼是偶然的。 這個:

return ( *(int*)a - *(int*)b );

實際上是在比較ARRAYS* arguments 的第一個元素,它之所以有效,是因為(a)結構的開頭沒有填充,(b) originNode在開頭,它實際上是一個int

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM