【问题标题】:Swapping two structs from an array of structs (bubblesort)从结构数组中交换两个结构(冒泡排序)
【发布时间】:2019-11-29 04:09:32
【问题描述】:

我有一个结构,它包含 3 个整数,每个整数类似于三角形一侧的大小:

struct triangle{
    int a; int b; int c;
};
typedef struct triangle tri;

我首先需要读取三角形的数量(n)。然后我读取了 n 个三角形的 3 条边,并按照三角形的面积从小到大对它们进行排序。

现在我的想法是比较这些区域,如果前者的面积大于后者,我就交换相应的结构。最后,结构体(边)的值会从小到大打印输出。

我一直在交换结构。到目前为止,我已经这样做了:

void swap(tri *a, tri *b)
{
    tri t;
    t = *a;
    *a = *b;
    *b = t;
}

void sort_by_area(tri *tr, int n)
{
    int sorted, storage[n];

    for(int i = 0; i <= n-1; i++)
    {
        storage[i] = give_area(&tr[i]);
    }

    do
    {
        sorted = 1;
        for(int i = 0; i < n-1; i++)
        {
            if(storage[i] > storage[i+1])
            {
                /*swap(tr[i].a, tr[i+1].a);
                swap(tr[i]->b, tr[i+1]->b);  
                swap(tr[i]->c, tr[i+1]->c);*/
              /*the commented section was my another attempt in which I would change the swap inputs to swap(int a, int b) or swap(int *a, int *b)*/

                swap(&tr[i], &tr[i+1]);
                sorted = 0;

            }
        }
    }while(!sorted);
}

我确定我在放入结构时绝对是完全错误的。

如果需要更多,这是我的主要功能:

int main()
{
    int n;
    scanf("%d\n", &n);
    tri *tr = malloc(n*(sizeof(tri)));

    for(int i = 0; i < n; i++){
        scanf("%d %d %d", &tr[i].a, &tr[i].b, &tr[i].c);
    }
    sort_by_area(tr, n);

    for(int i = 0; i < n; i++){
        printf("\n%d %d %d", tr[i].a, tr[i].b, tr[i].c);
    }
    free(tr);
return 0;
}

根据我的调查,代码可以正常工作,我认为主要问题在于交换函数或运行交换函数的嵌套 (for/if) 循环。

【问题讨论】:

  • 如果不确定编写一个简单的测试程序,只需使用定义的输入进行一次交换并打印结果。
  • 我同意@alk,而且根据this,交换功能看起来还可以。交换结构后,storage 会发生什么?
  • @xing 正确!我发布了一个答案来证明你的观点,如果你有时间看看! :)
  • @gsamaras 我猜存储会造成“内存泄漏”?...或者?
  • @alk 我按照你的建议试过了,效果很好,结构中的所有变量都被交换了。

标签: c pointers struct swap bubble-sort


【解决方案1】:

代码的问题是辅助数组storage在交换结构元素时保持不变。

其实没有必要有这个辅助数组。没有它你可以写

if( give_area(&tr[i] ) > give_area( &tr[i+1] ) )

否则你必须再添加一个交换函数,比如

void swap_storage(int *a, int *b)
{
    int t = *a;
    *a = *b;
    *b = t;
}

和已经定义好的函数swap一起使用

swap(&tr[i], &tr[i+1]);
swap_storage( &storage[i[, ^storage[i+1[ );

【讨论】:

  • 很好的回答弗拉德,+1,干得好!我冒昧地做了一个小的编辑以使其同质化,希望没关系.. :) PS:give_area() 方法可以通过 Heron 的公式来实现,就像我在回答中所做的那样..
  • @gsamaras Heron 的公式正是我所做的 :D 正如我所说,我遇到的唯一问题是交换问题,你们所有人都通过指出逻辑虚张声势帮助了我很多我做到了!
【解决方案2】:

交换方法很好。但是,您的方法存在逻辑错误。

您比较存储(区域),如果比较为真,则交换三角形,而不是区域。结果,第i个三角形不再必然对应第i个存储。

当它们各自的三角形被交换时,您也需要交换区域,如下所示:

(我使用double 来存储区域,但您仍然可以使用int 来存储它,但会丢失精度)

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

struct triangle{
    int a; int b; int c;
};
typedef struct triangle tri;

void swap(tri *a, tri *b)
{
    tri t;
    t = *a;
    *a = *b;
    *b = t;
}

void swap_double(double *a, double *b)
{
    double tmp = *a;
    *a = *b;
    *b = tmp;
}

// Heron's formula
double give_area(struct triangle *tr)
{
  double t = (tr->a + tr->b + tr->c)/2.0; /* Compute half of the perimeter */
  return sqrt(t * (t - tr->a) * (t - tr->b) * (t - tr->c)); /* Return area */
}

void sort_by_area(tri *tr, int n)
{
    int sorted;
    double storage[n];

    for(int i = 0; i <= n-1; i++)
    {
        storage[i] = give_area(&tr[i]);
    }

    do
    {
        sorted = 1;
        for(int i = 0; i < n-1; i++)
        {
            if(storage[i] > storage[i+1])
            {
                swap(&tr[i], &tr[i+1]);
                // Swap the areas too!!!
                swap_double(&storage[i], &storage[i + 1]);
                sorted = 0;

            }
        }
    }while(!sorted);
}

int main(void)
{
    int n;
    scanf("%d\n", &n);
    tri *tr = malloc(n*(sizeof(tri)));

    for(int i = 0; i < n; i++){
        scanf("%d %d %d", &tr[i].a, &tr[i].b, &tr[i].c);
    }
    sort_by_area(tr, n);

    for(int i = 0; i < n; i++){
        printf("\n%d %d %d", tr[i].a, tr[i].b, tr[i].c);
    }
    free(tr);
    return 0;
}

像这样编译:

gcc main.c -Wall -Wextra -lm
./a.out

输入:

2
7 8 9
4 5 6

输出:

4 5 6
7 8 9

调试提示:正如@a​​lk 提到的,当您不确定特定方法的正确性时,请编写一个简洁的程序来测试该方法(一个最小完整验证示例(MCVE),正如我们在 Stack 中所说的那样溢出)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-01-24
    • 1970-01-01
    • 1970-01-01
    • 2012-09-12
    • 2020-07-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多