Porgramming 공통

포인터 배열로 qsort 사용

macro 2010. 1. 19. 15:23
반응형

그냥 구조체 배열을 소팅하는데는, 구조체 크기와 소팅할 사이즈가 크면 성능에 문제가 생긴다.
이때는 포인터 배열을 하나 만들어놓고, 원래의 구조체 배열을 가르키게 한 다음에, 포인터 배열만 소팅을 하면 성능에 유리하다.
원래의 데이터 배열은 변화가 없고, 포인터만 소팅된다.
핵심은. 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)));
}

반응형