【问题标题】:General sorting for any type, struggling with structures任何类型的一般排序,与结构斗争
【发布时间】:2015-05-17 19:56:51
【问题描述】:

我在为任何类型实现通用排序算法时遇到了一些麻烦。我已经进行了一般排序,但我不知道如何为我制作的结构编写比较函数。这些结构是具有名称、型号年份和价格的汽车。我正在比较年份,并按升序对它们进行排序。

到目前为止,我已经编写了适用于通用算法的字符串排序函数。我相信一般的排序算法是正确编写的,它是在sort.c这里设计的:

#include "sort.h"
#include <string.h>


/* Swap two pointers.                                                                                                                                                                                          */
static
void swap(void** left, void** right) {
  void* temp = *left;
  *left = *right;
  *right = temp;
}

/* Sort Array                                                                                                                           
 * This function sorts the data stored in the array.
 * The actual sorting routine is                                                                    
 * Bubble-Sort.                                                                                                                         
 */
void sort_array(void* Array[], unsigned size, int (*compare)(void*,void*))
{
  int i;
  int have_swapped = 1;

  while (have_swapped) {
    have_swapped = 0;
    for (i = 0; i < size - 1; ++i ){
      if (compare(Array[i],Array[i+1])) {
        swap(&Array[i+1], &Array[i]);
        have_swapped = 1;
      }
    }
  }
}

我想我已经正确编写了compare_structs 的代码,但是当我尝试运行该程序时,它会在终端中进入一个无限循环。我不知道它为什么这样做。

我正在尝试学习 C 并将指针/函数作为参数传递。我想编写这个compare_structs 程序,使其符合sort.c 中的一般排序算法,所以我相信它必须返回-1 才能被交换。我找不到导致无限循环的错误。任何帮助表示赞赏!

这里是sort_structs.c

#include <stdio.h>
#include <string.h>
#include "sort.h"
#include <stdlib.h>

/* Automobile */
struct automobile {
  const char* name;
  unsigned year;
  unsigned price;
};

struct automobile one = { "AMC Pacer", 1975, 12900 };
struct automobile two = { "Cadillac Fleetwood", 1981, 4995 };
struct automobile three = { "Ford Pinto", 1971, 4200 };
struct automobile four = { "Suzuki X90", 1996, 1625 };
struct automobile five = { "Chrysler TC", 1991, 2495 };
struct automobile six = { "Cadillac Cimarron", 1986, 4990 };
struct automobile seven = { "Plymouth Prowler", 1997, 60000 };
struct automobile eight =  { "Ford Edsel", 1958, 17000 };
struct automobile nine =  { "Yugo", 1985, 3990 };
struct automobile ten =  { "Pontiac Aztek", 2001, 603 };

/* Test Data
 * Here I'm creating an array that points to the structures defined
 */
unsigned data_size = 10;
struct automobile* data[10] = {
  &one,
  &two,
  &three,
  &four,
  &five,
  &six,
  &seven,
  &eight,
  &nine,
  &ten
};

static
int compare_structs(void* left, void* right) {
  struct automobile *x = left;
  struct automobile *y = right;
  int xYear = x->year;
  int yYear = y->year;
  if (xYear > yYear) return -1;
}

/* Test program
 *
 * This program tests sort_array with an array of automobile objects.  Or
 * rather, an array of pointers to automobile objects.
 */
int main() {
  int i;
  int status = EXIT_SUCCESS;

  sort_array((void**)data, data_size, &compare_structs);
for(i = 0; i < data_size - 1; ++i) {
    if (data[i]->year > data[i+1]->year)  {
      fprintf(stderr, "\"%s\" and \"%s\" are out of order\n",data[i]->name, data[i+1]->name);
      status = EXIT_FAILURE;
    }
  }

  return status;
}

【问题讨论】:

  • 请剪掉你的代码段,只给我们看相关的部分。

标签: c sorting struct


【解决方案1】:

为了让代码正常运行,我做了很多更改。我会尽我所能回忆和解释它们。

1.调用 sort_array

你最初是这样调用 sort_array 的:

sort_array((void**)data, data_size, &amp;compare_structs);

虽然它需要 (a) 只需将数据变量转换为 void* 并且 (b) 在比较函数之前不需要地址运算符。 (如果你引用了一个函数但不调用它,则语句计算为函数的地址)

结果是:

sort_array((void*)data, data_size, compare_structs);

2。 compare_structs 的返回值 如果左侧的年份值大于右侧的年份值,则仅返回来自 compare_structs 的值。您应该返回 3 个值中的 1 个。 -1、0 和 1 方便升序/降序排序,0 表示不需要交换。

if (xYear &gt; yYear) return -1;

变成

return (xYear - yYear);

3.检查比较的返回值 您最初只检查退货是否是某物。您可以检查大于 0 或小于 0 以允许升序/降序排序。 因此,

if (compare(Array[i],Array[i+1]))

变成(升序排序)

if (compare(Array[i],Array[i+1]) &gt; 0)

整理这些修改并使用一个小模块运行结果以打印输出,从而将以下内容打印到控制台。

0. - 1958
1. - 1971
2. - 1975
3. - 1981
4. - 1985
5. - 1986
6. - 1991
7. - 1996
8. - 1997
9. - 2001

最后,完整的代码如下:

#include <stdio.h>
#include <string.h>
//#include "sort.h"
#include <stdlib.h>
//#include <string.h>


/* Swap two pointers.                                                                                                                                                                                          */
static
void swap(void** left, void** right)
{
    void* temp = *left;
    *left = *right;
    *right = temp;
}

/* Sort Array
 * This function sorts the data stored in the array.
 * The actual sorting routine is
 * Bubble-Sort.
 */
void sort_array(void* Array[], unsigned size, int (*compare)(void*,void*))
{
    int i;
    int have_swapped = 1;

    while (have_swapped)
    {
        have_swapped = 0;
        for (i = 0; i < size - 1; ++i )
        {
            if (compare(Array[i],Array[i+1]) > 0)
            {
                swap(&Array[i+1], &Array[i]);
                have_swapped = 1;
            }
        }
    }
    i = 100;
}





/* Automobile

 */
struct automobile
{
    const char* name;
    unsigned year;
    unsigned price;
};

struct automobile one =
{
    "AMC Pacer",
    1975,
    12900
};

struct automobile two =
{
    "Cadillac Fleetwood",
    1981,
    4995
};

struct automobile three =
{
    "Ford Pinto",
    1971,
    4200
};

struct automobile four =
{
    "Suzuki X90",
    1996,
    1625
};

struct automobile five =
{
    "Chrysler TC",
    1991,
    2495
};

struct automobile six =
{
    "Cadillac Cimarron",
    1986,
    4990
};

struct automobile seven =
{
    "Plymouth Prowler",
    1997,
    60000
};

struct automobile eight =
{
    "Ford Edsel",
    1958,
    17000
};

struct automobile nine =
{
    "Yugo",
    1985,
    3990
};

struct automobile ten =
{
    "Pontiac Aztek",
    2001,
    603
};

/* Test Data
 * Here I'm creating an array that points to the structures defined
 */
unsigned data_size = 10;
struct automobile* data[10] =
{
    &one,
    &two,
    &three,
    &four,
    &five,
    &six,
    &seven,
    &eight,
    &nine,
    &ten
};

static
int compare_structs(void* left, void* right)
{
    struct automobile *x = left;
    struct automobile *y = right;
    int xYear = x->year;
    int yYear = y->year;
    //if (xYear > yYear) return -1;
    return (xYear - yYear);
}
/* Test program
 *
 * This program tests sort_array with an array of automobile objects.  Or
 * rather, an array of pointers to automobile objects.
 */
int main()
{
    int i;
    int status = EXIT_SUCCESS;

    sort_array((void*)data, data_size, compare_structs);

    for(i = 0; i < data_size - 1; ++i)
    {
        if (data[i]->year > data[i+1]->year)
        {
            fprintf(stderr, "\"%s\" and \"%s\" are out of order\n",data[i]->name, data[i+1]->name);
            status = EXIT_FAILURE;
        }
    }

    for (i=0; i<data_size; i++)
        printf("%d. - %d\n", i, data[i]->year);

    return status;
}

【讨论】:

    猜你喜欢
    • 2017-02-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-17
    • 2020-09-18
    • 2018-05-23
    • 2013-11-08
    相关资源
    最近更新 更多