【问题标题】:Natural sort with qsort not workingqsort 的自然排序不起作用
【发布时间】:2018-05-24 15:05:31
【问题描述】:

我正在尝试对一组顶点进行排序,我需要制作的程序是为来自不同图形的顶点着色,为了更有效地做到这一点,我们使用不同的订单来贪婪运行,我的问题是当我尝试订购时它们按升序排列,我正在使用 qsort() 并且由于某种原因它在某些图形上不起作用,我不明白为什么,我将离开顶点的结构、比较函数以及我的函数'm 用来检查数组是否已排序。 顶点按名称进行比较(西班牙语中的名词)

类型定义:

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

【问题讨论】:

  • 与您的问题无关,但所有以下划线开头并后跟大写字母的符号(例如_Vertice_t)在所有范围内都保留。不要将它们用作您自己的名称和符号。另请注意,_t 后缀通常用于类型,而不是结构。
  • 与您的问题更相关,例如GrafoPVertice?请尝试创建Minimal, Complete, and Verifiable Example 向我们展示。
  • 很抱歉我没有包含我将编辑帖子的类型定义
  • @Someprogrammerdude 我在 _Grafo_t 结构中有一个 PVertice 数组,即 orden。
  • 我最喜欢比较相同无符号整数类型的两个数字ab 的方法类似于(a &gt; b) - (a &lt; b)。如果a 大于b,这将给出一个整数值 1,如果a 等于b,则给出一个整数值,或者如果a 小于b,则给出一个整数值,并且大无符号转换没有问题值转换为负符号值。

标签: c qsort


【解决方案1】:

假设int 与编译器的int32_t 大小相同,我不完全确定为什么您的原始文件不起作用。如果您的vertice1-&gt;nombre 小于vertice2-&gt;nombre,则vertice1-&gt;nombre-vertice2-&gt;nombre 的结果将是一个大的无符号值,超出32 位int 的范围。尽管实际结果是实现定义的,但大多数编译器只会将超出范围的值映射为负数。

当减去unsigned int 值时,“负”差最终会变成一个较大的unsigned int 值,超出int 的范围,因此结果将由实现定义。对于qsortbsearch 比较函数,仅使用返回值的符号(正、负或零),因此可以通过始终为“负”返回-1 来避免实现定义的结果差异,1 表示“正”差异,或 0 表示没有差异。有(至少)三种方法可以做到这一点:–

  1. 使用if 语句:

    if (a > b)
        result = 1;
    else if (a < b)
        result = -1;
    else
        result = 0;
    
  2. 使用条件运算符:

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

    result = (a > b) - (a < b);
    

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

如果 qsortbsearch 想要以相反顺序的值,则只需反转变量的顺序或反转比较运算符。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-01
    • 2015-09-27
    • 1970-01-01
    • 2021-07-28
    • 1970-01-01
    • 2012-01-11
    相关资源
    最近更新 更多