Question:
how to sort one element of a structure alphabetically c programming?
Zack
2012-04-05 18:36:50 UTC
I need help with my case 2, I want to sort the member's name in alphabetical order and display them

Here's my code -> http://ideone.com/Grk44

Thanks
Three answers:
husoski
2012-04-05 20:43:09 UTC
The only easy sorting methods rely on having the entire data set in memory. If that's possible, then your entire application could be streamlined by using an array (or linked list, but I think you'd use an array first.)



So, here's the test for whether you can expect your data to fit comfortably in memory.. You have 64 bytes of member record (right size, but wrong distribution. See below.) Multiply that by the number of members you expect this program to support. The result should be less that one fourth of your overall system memory. Looked at another way, divide your system memory by 4 times the record size (4*64 = 256) and that's the largest member database size you should ever consider. If you had 256MB (0.25 GB) of RAM, then you could handle up to a million gym members. If you have a million members, you can afford a computer with much more memory than that!



The data structure needs some more thought. The char join_date[10], for example. Is that supposed to be "mm/dd/yyyy"? If so, you need one more char for the '\0' string terminator. char join_date[11] as a minimum.



Is "int id[4]" really supposed to be an array of four ints? If it's four digits, then you just need a simple int. (...and 10,000 members will fit an any machine with memory measured in whole megabytes.)



There is a mixture of strings and ints. That's not good for effective memory use and it's even worse for portability. C aligns data in a processor-dependent fashion. I see 48 bytes of data, plus an array of 4 id numbers in your member record. You can be pretty successful if you put items intentionally on multiples of their largest divisor in (1,2,4,8). Having a 4-byte (presuming 32-bit ints) following a 10-byte name will waste 2 bytes on most compilers and fail to line to be portable on others. Put doubles first, ints and floats next, followed by short ints and chars. If a string has a multiple of 8 (total size including terminator) then you can move it up front. Try:



typedef struct

{

int id;

int age;

int weight;

int name[21];

char join_date[11];

char employment[21];

} member;



Then read in the data once from start to finish. At the beginning, you can use a fixed table size:



#define MAX_MEMBERS 4000 /* maximum number of members 8/

member mem_table[MAX_MEMBERS]; /* Table of members */

int num_members = 0; /* Current number of members in mem_table */



Then, open up your file, and read the whole table in with:



n = fread(mem_table, sizeof(member), MAX_MEMBERS, file_pointer);

if (0 != ferrror(file_pointer))

{

perror("file read error");

exit(1);

}

num_members = n;



That shows very simple error handling. A good idea, especially during debugging. Now, when you add a member: (1) check for num_members < MAX_MEMBERS; (2) add data into a your m_data struct, and (3) add to the table with mem_table[num_members++] = m_data.



FINALLY, the answer you your question. Use qsort(), from . First, make a comparison function that compares names. It uses strcmp() from :



int compare_names(void *left, void *right)

{

member *lp = (member*)left, *rp = (member*)right;

return strcmp(lp->name, rp->name);

}



Then, sort the array with:



qsort(mem_table, num_members, sizeof(member), compare_names);



Sorting is the easy part.
Motorhead
2012-04-05 19:04:04 UTC
Not bad so far, but you don't have any sort of data structure to put all the individual member structs into, in order to be able to sort them.

I would probably suggest using a STL container, like a Vector.

You could do it yourself with pointers, but it hardly seems worth bothering because a Vector has a built in sort method.

The linear file you are reading them in from could also be used, but it would be much slower.

You could have to do a bubble sort, where you traverse in 2 nested for loops, swapping 2 member structs at a time, and only those 2 needing to be in memory.
2016-02-24 00:54:34 UTC
Depending on how long your linked list is, you might have an option to do this: Buffer a list of pointers which address at least some of the entries in the list, using a 'page table' structure that you could apply quicksort or a B+ tree sort to. That way you can pass buffer addresses to the sort rather than having to build a special sort routine which has a built-in linked list traversal to cover the whole linked list. The buffer addresses could be treated to a certain extent like binary sort index entries, at least as far as page insertion points goes; and if you partition the way quicksort does, you wouldn't need to worry about the pointers themselves as long as your compare routine dereferences them. Passing only the pointers to the data records requires an additional level of pointer indirection, because the pointers are in buffers rather than being encountered directly during a traversal, but it also frees the pre-sort ordering from the sort itself and no links in the list need be modified until you retrieve the sorted list from your sort routine.


This content was originally posted on Y! Answers, a Q&A website that shut down in 2021.
Loading...