그냥 구조체 배열을 소팅하는데는, 구조체 크기와 소팅할 사이즈가 크면 성능에 문제가 생긴다.
이때는 포인터 배열을 하나 만들어놓고, 원래의 구조체 배열을 가르키게 한 다음에, 포인터 배열만 소팅을 하면 성능에 유리하다.
원래의 데이터 배열은 변화가 없고, 포인터만 소팅된다.
핵심은. compare 함수다.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LEN_NAME 22
#define cp_string(A,B) strncpy(A,B,strlen(B))
typedef struct elem_data{
int num;
char name[LEN_NAME];
short age;
}ELEM_DATA;
int n_elem;
void print_elem(const ELEM_DATA *dest);
int add_elem(ELEM_DATA *dest, int num, const char *name, short age);
int comp_elem_data(const void *s1, const void *s2);
int comp_elem_name(const void *s1, const void *s2);
int main()
{
ELEM_DATA *p_elem_data, *p_search_elem_data, key_elem_data;
// search result point array
ELEM_DATA *search[10];
int j ;
int i;
if((p_elem_data = (ELEM_DATA *)calloc(10, sizeof(ELEM_DATA))) == NULL){
exit(1);
}
ELEM_DATA *name = p_elem_data;
add_elem(&p_elem_data[n_elem], 1, "paul", 42);
add_elem(&p_elem_data[n_elem], 5, "kate", 33);
add_elem(&p_elem_data[n_elem], 11, "s.kim", 29);
add_elem(&p_elem_data[n_elem], 32, "t.mikimoto", 17);
add_elem(&p_elem_data[n_elem], 37, "paul", 22);
add_elem(&p_elem_data[n_elem], 55, "risa", 21);
add_elem(&p_elem_data[n_elem], 27, "david kim", 32);
for (j = 0; j < 10; j++){
search[j] = &p_elem_data[j];
printf("%s ", search[j]->name);
}
printf("(*) before qsort : \n");
for (i = 0; i<n_elem; i++) print_elem(search[i]);
qsort(search, n_elem, sizeof(ELEM_DATA*), comp_elem_data);
printf("(*) After qsort : \n");
for(i = 0; i<n_elem;i++) print_elem(&p_elem_data[i]);
printf("\n");
for(i = 0; i<n_elem;i++) print_elem(search[i]);
return 0;
}
void print_elem(const ELEM_DATA *dest)
{
printf("\t[ %2d | %-*s | %02d ] \n", dest->num, sizeof(dest->name), dest->name, dest->age);
}
int add_elem(ELEM_DATA *dest, int num, const char *name, short age)
{
memset(dest, 0, sizeof(ELEM_DATA));
dest->num = num;
strncpy(dest->name, name, LEN_NAME);
dest->age = age;
n_elem++;
return 0;
}
int comp_elem_data(const void *s1, const void *s2)
{
return (memcmp( &((**(ELEM_DATA **)s1).age), &((**(ELEM_DATA **)s2).age), sizeof(short)));
}