Here is my code for a bubble sort that is supposed to put the customer structs in order by the last name of the customer that is read in by ...last_customer. I am not sure why it isn't working.
void sort_customers (struct customers *p_info, int num_customers) {
struct customers *p_temp,
*p_walker;
int current;
for (current = 0; current < (num_customers-1); current ) 0
for(p_walker = p_info; (p_walker-p_info) > current; p_walker--)
if (strcmp(p_walker->last_name, (p_info)->last_name) != 0)
{
p_temp = p_walker;
p_walker = p_info;
p_info = p_temp;
}
return;
}
Given the ideal input: Jones, Smith, Allen
This would be the ideal output: Allen, Jones, Smith
As you can see this loop is supposed to set the structures in order so that when i call the structure last names in a print function, they will appear in order.
CodePudding user response:
Problems
Hey, I think I found several problems in your code.
- Both of your for loops don't have any
{}
first loop
- by using
(num_customers-1)
you skipped one element.
second loop
- the
for
loop is never executed. Your condition is never met. - if you decrement the
p_walker
u "walk" in the wrong direction. I believe your pointerp_info
is the lowest pointer in the array. - in general, I think the pointer arithmetic in the for loop is causing a lot of problems in readability and understanding. I personally would do the pointer arithmetic after you calculated your indexes in the loops.
void bubblesort(int array[], int length)
{
int i, j, tmp;
for (i = 1; i < length; i )
{
for (j = 0; j < length - i; j )
{
if (array[j] > array[j 1])
{
tmp = array[j];
array[j] = array[j 1];
array[j 1] = tmp;
}
}
}
}
if statement
- you compared all your values you walked through with the start of your vector at
p_info
. I believe in typical bubble sort, you would compare with the next neighbor. != 0
in your if statement would be true when the values(Strings) are greater and also if they are lesser. They would just switch all the time if the strings are not equal.
swap
- one of the swapping strings was at
p_info
. This would destroy your reference to the beginning of the string. And possible cause a seg-fault error. - if you want to use pointer arithmetic in the index of the second for-loop u need to swap the values of your structs and not only the pointers.
Possible Solution
Your function in a way it should work.
void sort_customers (struct customers *p_info, int num_customers){
struct customers *p_walker;
struct customers temp;
int current;
for (current = 0; current < num_customers; current ){
printf("%s\n", "1");
for(p_walker = p_info; p_walker < p_info (num_customers-current-1); p_walker ){
printf("%s\n", "2");
if (strcmp(p_walker->last_name, (p_walker 1)->last_name) > 0)
{
temp = *p_walker;
*p_walker = *(p_walker 1);
*(p_walker 1) =temp;
}
}
}
return;
}
the input p_info
is expected as a pointer to an array of struct customers *
that are defined as followed:
struct customers{
char* last_name;
};
CodePudding user response:
Some issues that I found:
for(p_walker = p_info; (p_walker-p_info) > current; p_walker--)
will not execute ever, as p_walker-p_info is 0 (after setting them to the same value that is).
strcmp does not directly tell you which last_name is alphabetically "later", only that they are different. So your code would swap the two customers always if they were of different name.
I tried to fix the code and came up with this (quite different):
void sort_customers (customers *p_info, int num_customers)
{
customers *p_temp = 0;
do
{
for (int i = 1; i <= num_customers - 1; i )
{
if (strcmp( p_info[i].last_name, p_info[i-1].last_name) != 0)
{
for (int idx = 0; idx < strlen( p_info[i].last_name); idx )
{
if (p_info[i].last_name[idx] < p_info[i-1].last_name[idx])
{
/* found a difference, and i-1 th element is bigger (i.e. later in the alphabet) */
memcpy(p_temp, &p_info[i], sizeof(customers));
memcpy(&p_info[i], &p_info[i-1], sizeof(customers));
memcpy(&p_info[i-1], p_temp, sizeof(customers));
}
break;
}
}
}
num_customers--;
}while(num_customers > 1);
return;
}
An example main function with
typedef struct
{
char last_name[5];
} customers;
int main (void)
{
customers c[6] = {{"ghi"},{"abc"}, {"def"}, {"hij"}, {"sdf"}, {"auf"}};
sort_customers(c, 6);
for (int i = 0; i<6; i )
printf ("c[%d].last_name = %s\n", i, c[i].last_name);
return -1;
}
returns:
c[0].last_name = abc
c[1].last_name = auf
c[2].last_name = def
c[3].last_name = ghi
c[4].last_name = hij
c[5].last_name = sdf