使用合并排序对结构数组进行排序

马蒂姆·科雷亚(Martim Correia)

因此,我有一个称为的结构,product并且有一系列产品。

我正在尝试使用合并排序按产品价格对数组进行排序,问题是我的代码没有交换任何内容,我也不明白为什么。如果有人可以帮助我,我将不胜感激。

结构体:

typedef struct product {
    int ident;      /* idp of a product */
    char desc[64];  /* string that describes a product eg. "bread" */
    int price;      /* price of the product */
    int weight;     /* weight of the product eg. 2kg */
    int quant;      /* quantity of the product in stock */
    int state_prod; /* state of a product, if 1 it is in the system else is 0 and is not in the sistem */
} product;

合并排序算法

void mergesort_price(product a[], int left, int right) {
    int m = (right + left) / 2;
    if (right <= left)
      return;
    mergesort_price(a, left, m);
    mergesort_price(a, m + 1, right);
    merge_price(a, left, m, right);
}

void merge_price(product a[], int left, int m, int right) { 
    int i, j, k;
    for (i = m + 1; i > left; i--) 
        aux[i - 1] = a[i - 1];
    for (j = m; j < right; j++)
        aux[right + m - j] = a[j + 1];
    for (k = left; k <= right; k++)
        if (aux[j].price < aux[i].price || i > m)
            a[k] = aux[j--];
        else
        if ((aux[j].price == aux[i].price) || i > m) {
            if ((aux[j].ident < aux[i].ident) || i > m) {
                a[k] = aux[j--];
            }
        } else
            a[k] = aux[i++];
}

例:

我的输入:

desc: pao, price:2, weight: 2, quant:200
desc: ovos, price:1, weight: 1, quant:100
desc: iscas, price:3, weight: 3, quant:300
desc: fiambre, price:2, weight: 2, quant:200
desc: queijo, price:2, weight: 2, quant:200

正确的输出:

desc: ovos, price:1, weight: 1, quant:100
desc: pao, price:2, weight: 2, quant:200
desc: fiambre, price:2, weight: 2, quant:200
desc: queijo, price:2, weight: 2, quant:200
desc: iscas, price:3, weight: 3, quant:300

程序:

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

#define MAX_PROD 10000 /* max products in the system */

typedef struct product {
   int ident;      /* idp of a product */
   char desc[64];  /* string that describes a product eg. "bread" */
   int price;      /* price of the product */
   int weight;     /* weight of the product eg. 2kg */
   int quant;      /* quantity of the product in stock */
   int state_prod; /* state of a product, if 1 it is in the system else is 0 and is not in the system */
} product;

product p1 = { 0, "pao", 2, 2, 200, 1 };
product p2 = { 1, "ovos", 1, 1, 100, 1 };
product p3 = { 2, "iscas", 3, 3, 300, 1 };
product p4 = { 3, "bacon", 2, 5, 400, 1 };
product p5 = { 4, "abacate", 2, 6, 500, 1 };

product sistem[5] = {};  /* array that contains the products */
product sistem2[5] = {}; /* Will be used has a copy of sistem */

sistem[5] = { p1, p2, p3, p4, p5}
product aux[5]; /* Auxliar array used in mergesort */

void mergesort_price(product a[], int left, int right) {
    int m = (right + left) / 2;
    if (right <= left)
        return;
    mergesort_price(a, left, m);
    mergesort_price(a, m + 1, right);
    merge_price(a, left, m, right);
}

void merge_price(product a[], int left, int m, int right) { 
    int i, j, k;
    for (i = m + 1; i > left; i--) 
        aux[i - 1] = a[i - 1];
    for (j = m; j < right; j++)
        aux[right + m - j] = a[j + 1];
    for (k = left; k <= right; k++)
        if (aux[j].price < aux[i].price || i > m)
            a[k] = aux[j--];
        else if ((aux[j].price == aux[i].price) || i > m) {
            if ((aux[j].ident < aux[i].ident) || i > m) {
                a[k] = aux[j--];
            }
        } else
            a[k] = aux[i++];
}

void print_array(product arr[]) {
    int i;
    for (i = 0; i < 5; i++) {
         printf("* %s %d %d %d\n", arr[i].desc, arr[i].price, arr[i].quant, arr[i].ident);
    }
}

void copy_el(product source[], product dest[], int size) {
    int i;
    for (i = 0; i < size; i++) {
        dest[i] = source[i];
    }
}

int main() {   
    copy_el(sistem, sistem2, 5);
    printf("The products in the system are:\n");
    print_array(sistem);

    printf("\nSorted products by price in the system:\n");
    mergesort_price(sistem2, 5, 0);
    print_array(sistem2);

    return 0;
}

我知道我输入的输入没有在程序中编码,我只是以这种方式给出的输入作为示例,以使其更易于理解。

克雷格·埃斯蒂

记得我在上面提到的意见,你的for回路初始化ijk

您的排序看起来有点复杂。

有两种方法可以进行合并:

(1)复制到临时数组并合并回原始文件(这就是您正在做的事情)

(2)从原始的左/右数组合并到temp数组,然后将结果复制回原始数组(对我来说似乎更简单)

无论如何,这是重构版本:

#include <stdio.h>

typedef struct product {
    int ident;                          /* idp of a product */
    char desc[64];                      /* string that describes a product eg.
                                            "bread" */
    int price;                          /* price of the product */
    int weight;                         /* weight of the product eg. 2kg */
    int quant;                          /* quantity of the product in stock */
    int state_prod;                     /* state of a product, if its 1 its in
                                            the system else is 0 and is not in
                                            the system */
} product;

#define AMAX    28
product a[AMAX];
product aux[AMAX];

void merge_price(product a[], int low, int mid, int high);

void
mergesort_price(product a[], int low, int high)
{
    int mid = (high + low) / 2;

    if (high <= low)
        return;
    mergesort_price(a, low, mid);
    mergesort_price(a, mid + 1, high);
    merge_price(a, low, mid, high);
}

void
merge_price(product a[], int low, int mid, int high)
{
    int right;
    int left;
    int k;
    int i;

    k = 0;
    left = low;
    right = mid + 1;

    for (;  (left <= mid) && (right <= high);  ++k) {
        if (a[left].price <= a[right].price)
            aux[k] = a[left++];
        else
            aux[k] = a[right++];
    }

    for (;  left <= mid;  ++left, ++k)
        aux[k] = a[left];

    for (;  right <= high;  ++right, ++k)
        aux[k] = a[right];

    k = low;
    i = 0;
    for (;  k <= high;  ++k, ++i)
        a[k] = aux[i];
}

void
show(void)
{
    for (int idx = 0;  idx < AMAX;  ++idx)
        printf(" %d",a[idx].price);
    printf("\n");
}

int
main(void)
{

    for (int idx = 0;  idx < AMAX;  ++idx)
        a[idx].price = AMAX - idx;
    show();

    mergesort_price(a,0,AMAX - 1);
    show();
}

更新:

好的,它工作了,谢谢,但是当我尝试这样做但是对于字符串却没有用。我只是真正地更改了if语句,就像你能解释为什么它没有请。

好的,我已经创建了一个生成随机产品描述并按排序的版本price然后根据desc[字符串排序]求助。

我使用指向比较函数的指针来完成此操作,该指针作为附加参数传递给现有函数。这类似于libcqsort函数的最后一个参数

可以将其扩展为“多键”排序(例如price[或您希望的任何成员]然后desc[ struct]排序)。请参阅:cmpbybothcmpbyall

请注意,乍看之下,编译器可能会比选择(例如)内联[简单]函数cmpbyall要快,因此,两个函数都可以生成完全相同的可执行代码。cmpbyboth-O2

无论如何,这是代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#define STRMAX      64
#define GENSTR      7

typedef struct product {
    int ident;                          /* idp of a product */
    char desc[STRMAX];                  /* string that describes a product eg.
                                            "bread" */
    int price;                          /* price of the product */
    int weight;                         /* weight of the product eg. 2kg */
    int quant;                          /* quantity of the product in stock */
    int state_prod;                     /* state of a product, if its 1 its in
                                            the system else is 0 and is not in
                                            the system */
} product;

typedef int (*cmpfnc_p)(const product *,const product *);

#define AMAX    28
product a[AMAX];
product aux[AMAX];

void merge_price(product a[], int low, int mid, int high,cmpfnc_p cmpfnc);

void
mergesort_price(product a[], int low, int high, cmpfnc_p cmpfnc)
{
    int mid = (high + low) / 2;

    if (high <= low)
        return;
    mergesort_price(a, low, mid, cmpfnc);
    mergesort_price(a, mid + 1, high, cmpfnc);
    merge_price(a, low, mid, high, cmpfnc);
}

void
merge_price(product a[], int low, int mid, int high,cmpfnc_p cmpfnc)
{
    int cmpflg;
    int right;
    int left;
    int k;
    int i;

    k = 0;
    left = low;
    right = mid + 1;

    for (;  (left <= mid) && (right <= high);  ++k) {
        cmpflg = cmpfnc(&a[left],&a[right]);
        if (cmpflg <= 0)
            aux[k] = a[left++];
        else
            aux[k] = a[right++];
    }

    for (;  left <= mid;  ++left, ++k)
        aux[k] = a[left];

    for (;  right <= high;  ++right, ++k)
        aux[k] = a[right];

    k = low;
    i = 0;
    for (;  k <= high;  ++k, ++i)
        a[k] = aux[i];
}

void
show(const char *tag)
{

    printf("\n");
    printf("%s",tag);

    for (int idx = 0;  idx < AMAX;  ++idx)
        printf(" %s=%d",a[idx].desc,a[idx].price);

    printf("\n");
}

// genstr -- get random string
void
genstr(char *desc)
{
    int len;
    int idx;
    int chr;
    int carry;

    // get random string length
    len = (rand() % GENSTR) + 1;

    // fill in random string
    for (idx = 0;  idx < len;  ++idx) {
        chr = rand() % 26;
        chr += 'a';
        *desc++ = chr;
    }

    *desc = 0;
}

// cmpbyprice -- compare by price
int
cmpbyprice(const product *left,const product *right)
{
    int cmpflg;

    cmpflg = left->price - right->price;

    return cmpflg;
}

// cmpbydesc -- compare by description
int
cmpbydesc(const product *left,const product *right)
{
    int cmpflg;

    cmpflg = strcmp(left->desc,right->desc);

    return cmpflg;
}

// cmpbyboth -- compare by price description
int
cmpbyboth(const product *left,const product *right)
{
    int cmpflg;

    do {
        cmpflg = cmpbyprice(left,right);
        if (cmpflg)
            break;

        cmpflg = cmpbydesc(left,right);
        if (cmpflg)
            break;

        // add more if you like ...
    } while (0);

    return cmpflg;
}

// cmpbyall -- compare by price description [faster version]
int
cmpbyall(const product *left,const product *right)
{
    int cmpflg;

    do {
        cmpflg = left->price - right->price;
        if (cmpflg)
            break;

        cmpflg = strcmp(left->desc,right->desc);
        if (cmpflg)
            break;

        // add more if you like ...
    } while (0);

    return cmpflg;
}

int
main(int argc,char **argv)
{
    unsigned int seed;
    product *ptr;

    --argc;
    ++argv;

    if (argc > 0)
        seed = atoi(*argv);
    else
        seed = time(NULL);
    printf("SEED: %u\n",seed);
    srand(seed);

    for (int idx = 0;  idx < AMAX;  ++idx) {
        ptr = &a[idx];
        ptr->price = AMAX - idx;
        genstr(ptr->desc);
    }
    show("INITED");

    mergesort_price(a,0,AMAX - 1,cmpbyprice);
    show("BYPRICE");

    mergesort_price(a,0,AMAX - 1,cmpbydesc);
    show("BYDESC");

    mergesort_price(a,0,AMAX - 1,cmpbyboth);
    show("BYBOTH");

    mergesort_price(a,0,AMAX - 1,cmpbyall);
    show("BYALL");
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

使用合并排序对数组进行排序

来自分类Dev

使用JS Underscore对相似数组进行key合并排序

来自分类Dev

合并排序-使用整数数组对字符串数组进行排序

来自分类Dev

合并排序变体:使用链接数组

来自分类Dev

是否可以使用合并排序(C#)根据多个条件对数组进行排序?

来自分类Dev

是否可以使用合并排序对堆栈进行排序?

来自分类Dev

使用具有2个数组作为参数的合并函数进行合并排序

来自分类Dev

使用合并排序排序(名称)

来自分类Dev

使用合并排序/快速排序对Python中的类对象的属性进行排序

来自分类Dev

数组中的反转计数数。使用合并排序

来自分类Dev

数组中的反转计数数。使用合并排序

来自分类Dev

如何使用usort对合并数组进行排序?

来自分类Dev

当对一百万个元素的数组进行排序时,如何找到合并排序算法崩溃的原因?

来自分类Dev

使用qsort对结构指针数组进行排序

来自分类Dev

如何使用qsort对结构数组进行排序

来自分类Dev

使用qsort对结构指针数组进行排序

来自分类Dev

在Int C ++数组上合并排序

来自分类Dev

合并排序二维数组

来自分类Dev

使用比较器或合并排序,对对象的arrayList进行排序哪个更好?

来自分类Dev

使用合并排序,以O(n log n)的时间对链表进行排序

来自分类Dev

合并时合并排序使用什么排序技术

来自分类Dev

合并排序与选择排序

来自分类Dev

分而治之:合并排序

来自分类Dev

合并排序

来自分类Dev

合并排序算法

来自分类Dev

合并排序比较

来自分类Dev

合并排序对

来自分类Dev

合并排序比较

来自分类Dev

使用递归合并排序算法

Related 相关文章

热门标签

归档