15,741,818 members
1.00/5 (1 vote)
See more:
``` struct triangle
{
int a;
int b;
int c;
};

typedef struct triangle triangle1;

void sort_by_area(triangle1* tr, int n)
{
int i,j,temp;
int *p=(int *) calloc(100, sizeof(int));
int *s=(int *) calloc(100, sizeof(int));
for(i=0;i<n;i++)
{
p[i]=(tr[i].a + tr[i].b + tr[i].c) / 2;
s[i]= p[i] * (p[i]-tr[i].a) * (p[i]-tr[i].b) * (p[i]-tr[i].c);
s[i]=sqrt(s[i]);
}

for(i=0;i<n-1;i++)
{
for(j=0;j<(n-i)-1;j++)
{
if(s[j]>s[j+1])
{
triangle1 temp_tr = tr[j];
tr[j] = tr[j+1];
tr[j+1] = temp_tr;
}
}
}

free(p);
free(s);
}```

What I have tried:

`I know that the outer loop is used to iterate between the elements of the array and the second one used to compare and swap between the elements, but I cannot understand the logic of the inner loop unlike the outer one which is a basic one and easy for understanding, why j<(n-i)-1??`
Posted
Updated 24-Feb-23 10:48am
RedDk 24-Feb-23 14:38pm
I suggest that HOWEVER you're using this module in your MAIN, you do whatever is required to compile an executable and then run the debugger with copious breakpoint and listing of variables. During that session you'll even be able to answer your own questions by typing in temporary variable and even do some basic arithmetic like accumulate sums. Whole equations such as "j<(n-1)-1" will have registration and if you observe in the interface, you'll even have access to binary conversions while "stepping through".
Gerry Schmitz 24-Feb-23 14:38pm
The inner loop (of the 2nd) is doing the comparing and swapping; the 2nd outer loop moves the the compare and swap along; the previous element now being in lo order. The inner loop is shortened by the amount the outer loop was advanced (i).

## Solution 2

That is how bubble sort works, see, for instance this page: Bubble sort in C | Programming Simplified[^].
Such code, however, is flawed. For instance, when swapping triangles it doesn't swaps the triangle areas as well. Moreover it performs truncating operations (division and sqare root) on integers.
Try
C
```#include <stdio.h>
#include <stdlib.h>
#include <math.h>
typedef struct Triangle
{
unsigned a;
unsigned b;
unsigned c;
} Triangle;

// compute (4 * squared area) of a triangle
// this way division and square root are avoided while ordering is maintained
unsigned fts_area(Triangle * t)
{
unsigned p = t->a + t->b + t->c; // perimeter
unsigned  fts = p * ( p - 2* t->a) * (p - 2 * t->b) * (p - 2 * t->c); // 4 times the squared area
return fts;
}

void sort_by_area(Triangle tr[], unsigned n)
{
unsigned * a = (unsigned *) malloc(n * sizeof(unsigned));
if (! a )
return; // todo: print an error message

for (unsigned i=0; i<n; ++i)
{
a[i] = fts_area(&tr[i]);
}

for( unsigned i=0; i<n-1; ++i)
{
for (unsigned j=0; j<(n-i)-1; ++j)
{
if(a[j] > a[j+1])
{
Triangle temp_tr = tr[j]; // swap the triangles
tr[j] = tr[j+1];
tr[j+1] = temp_tr;

unsigned temp_a = a[j]; // swap their 'areas' as well
a[j] = a[j+1];
a[j+1] = temp_a;
}
}
}
free(a);
}

#define TRIANGLES 4

int main()
{
Triangle tr[TRIANGLES] = { {2,3,4}, { 100, 42, 80},  { 10, 11, 15}, { 2,2, 3}};

sort_by_area( tr, TRIANGLES);

for ( unsigned n = 0; n < TRIANGLES; ++n)
{
double area =  sqrt(fts_area(&tr[n])) / 4;
printf("{ %u , %u, %u }, %g\n", tr[n].a, tr[n].b, tr[n].c, area);
}

}```

RedDk 25-Feb-23 14:08pm
Clearly, the answer on which the OP should bank.

## Solution 1

Because you index on `j + 1` inside the loop.
Run the code in the debugger and watch what happens - you'll see what I mean.

And anyway, it a basic homework question and you wrote the code so why don't you understand it already?