qsort无效的自然排序

时间:2018-05-24 15:05:32

标签: c qsort

我正在尝试对顶点数组进行排序,我需要做的程序是从不同的图形中着色顶点,为了更有效地使用不同的命令来运行贪婪,我的问题是当我尝试订购时它们按升序排列,我使用qsort(),由于某种原因,它不能在某些图形上工作,我无法理解为什么,我将离开顶点的结构,比较函数以及我用来检查数组的函数是否已排序。 正在通过名称(西班牙语中的nombre)来比较顶点

类型定义:

typedef uint32_t u32; /* Definición de tipo u32 */
typedef struct _Vertice_t *PVertice;
typedef struct _Grafo_t *Grafo;

顶点:

/* Definición de Estructura Vertice */
struct _Vertice_t {
    u32 nombre; /* Nombre real del vértice */
    u32 grado; /* Grado del vértice */
    u32 color; /* Color del vértice  */
    u32 index; /* Indice */
        u32 mem_vecinos;
        u32 tag;
        bool visitado;/*variable para saber el numero de componentes conexas*/
        u32 x_aleatorio;/* u32 para uso exclusivo en funcion orden aleatorio */
        u32 aleatorio; /* u32 para uso exclusivo en funcion orden aleatorio */
    u32 cant_de_colores; //uso exclusivo para orden bloque  == 1
    PVertice *vecinos; /* Vecinos del vértice */
};

图表:

/* Definición de Estructura Grafo */
struct _Grafo_t {
    u32 nro_vertices; /* Cantidad de vértices del Grafo */
    u32 nro_lados; /* Cantidad de lados del Grafo */
    u32 nro_colores; /* Cantidad de colores usados para colorear el Grafo */
    PVertice vertices; /* Arreglo de Vértices del Grafo */
        bool *facil_busqueda;
    PVertice *orden; /* Arreglo indicador del orden de los vértices del Grafo*/
};

比较功能:

int cmpfunc (const void * a, const void * b) {
    PVertice vertice_1 = *(PVertice*)a;
    PVertice vertice_2 = *(PVertice*)b;
  int resultado = ( vertice_1->nombre )-(vertice_2->nombre);
    return resultado;
}

排序:

void OrdenNatural(Grafo G) {
    qsort(G->orden, G->nro_vertices, sizeof(PVertice), cmpfunc);
}

最后我如何检查它是否已分类:

bool arrayIsSorted(PVertice *a, u32 n) {
  if ((n == 1) || (n == 0))
    return true;

  if (a[n-1]->nombre < a[n-2]->nombre) {
    printf("%u %u\n", a[n-1]->nombre, a[n-2]->nombre);
    return false;
  }

  return arrayIsSorted(a, n-1);
}

我在终端上运行时从1个特定图形得到的结果:

2 4294965727

0

The Graph

1 个答案:

答案 0 :(得分:1)

我不完全确定为什么原始版本无效,因为int与编译器的int32_t大小相同。如果您的vertice1->nombre小于vertice2->nombre,那么vertice1->nombre-vertice2->nombre的结果将是一个大的无符号值,超出32位int的范围。大多数编译器只会将超出范围的值映射到负数,尽管实际结果是实现定义的。

当减去unsigned int值时,“负”差异将最终为unsigned int的超出范围的大int值,因此结果将是实现-defined。对于qsortbsearch比较函数,仅使用返回值的符号(正数,负数或零),因此可以通过始终返回{{1}来避免实现定义的结果}为“负”差异,-1为“正”差异,或1为无差异。有(至少)三种方法可以实现这一目标: -

  1. 使用0语句:

    if
  2. 使用条件运算符:

    if (a > b)
        result = 1;
    else if (a < b)
        result = -1;
    else
        result = 0;
    
  3. 使用比较差异:

    result = a > b ? 1 : (a < b ? -1 : 0);
    

    (这是3个选项中“最聪明的”,虽然可能不是最清楚的)。

  4. 如果result = (a > b) - (a < b); qsort想要反向排列的值,则只需颠倒变量的顺序或反转比较运算符。