C 레퍼런스
15 탐색과 정렬
이 장은 배열을 탐색하고 정렬하기 위한 함수들을 설명하고 있다. 당신은 배열에 있는 objects의 크기와 요소의 전체개수와 함께, 인수로써 적당한 비교 함수를 줄 수 있다.
15. 1 비교 함수 정의하기
배열을 정렬하는 라이브러리 함수를 사용하기 위해서, 당신은 어떻게 그 배열의 요소들을 비교할 것인지 알려줘야만 한다. 이것을 하기 위해, 당신은 배열의 두 개의 요소를 비교하기 위한 비교함수를 공급한다. 그 라이브러리는 비교하기 위한 두 개의 배열 요소들을 가리키는 포인터가 인수로써 주어지면, 이 함수를 호출할 것이다. 당신의 비교함수는 strcmp( 5. 5절 [String/Array Comparison] 참조)가 하는 방법으로 값을 반환하는데, 그 방법이란 첫 번째 인수가 두 번째 인수보다 작으면 음수를 반환하고, 만일 같으면 0을 반환하고, 첫 번째가 크면 양수를 반환한다. 이곳에서는 double형의 숫자들로 이루어진 배열을 가지고 작업하는 비교함수의 예가 있다.
- int
- compare_doubles (const double *a, const double *b)
- {
- return (int) (*a - *b);
- }
- compare_doubles (const double *a, const double *b)
헤더파일 'stdlib. h'는 비교함수들의 데이터 타입을 위한 이름을 정의하고 있다. 이 타입은 GNU 확장이다.
int comparison_fn_t (const void *, const void *);
15. 2 배열 탐색 함수
정렬된 배열에서 키(key)값과 같은 요소를 탐색하기 위해서는, bsearch함수를 사용하라. 이 함수를 위한 프로토타입은 헤더파일 'stdlib. h'에 있다.
함수 : void *bsearch (const void *key, const void *array, size_t count, size_t size, comparison_fn_t compare)
- bsearch 함수는 key 와 동등한 오브젝트를 정렬된 배열 array에서 찾는다. 그 배열은 size 바이트의
크기를 가진, count 개의 요소를 갖는다. compare 함수는 비교를 수행하는데 사용된다. 이 함수는
두 개의 포인터 인수로 호출되고 첫 번째 인수가 두 번째 인수보다 적거나, 같거나, 또는 큼에
해당하는 정수를 반환한다. 배열의 요소들은 이 비교함수에 의하여 오름차순으로 미리
정렬되어져야만 한다.
- 반환값은 key값과 같은 배열의 요소를 가리키는 포인터이거나, 또는 같은 요소를 발견하지 못하면 널 포인터를 반환한다. 만일 그 배열이 key값과 같은 것을 한 개 이상 가지고 있다면, 반환된 것은 정해지지 않았다. 이 함수는 바이너리 탐색 알고리즘을 사용해서 동작한다는 것에 기인하여 bsearch라는 이름이 유래됐다.
15. 3 배열 정렬 함수
비교 함수를 사용하여 배열을 정렬하기 위해서는, qsort 함수를 사용하라. 이 함수를 위한 프로토타입은 'stdlib. h'에 있다.
함수 : void qsort (void *array, size_t count, size_t size, comparison_fn_t compare)
- qsort 함수는 배열 array를 정렬한다. 그 배열은 size의 크기를 가진 count개의 요소를 갖는다. compare 함수는 배열 요소들의 비교를 수행하는데 사용된다. 이 함수는 두 개의 포인터 인수로 호출되고 첫 번째 인수가 두 번째 인수와 비교해서 큰지, 같은지, 적은지를 알 수 있는 값을 반환한다.
만일 당신이 안정적인 정렬을 원한다면, 당신은 두 개의 요소사이에 부족한 다른 측면의 차이나, 그들의 주소로 그들을 비교하는 것과 같은 비교 함수를 써서 이 결과를 얻을 수 있다.
이곳은 위에 정의된 비교 함수를 사용해서, 숫자 순서로 double형의 배열을 정렬하는 예를 보여주고 있다. ( 15. 1 [Comparison Functions] 참조. )
- {
- double *array;
- int size;
- . . .
- qsort (array, size, sizeof (double), compare_doubles);
- int size;
- }
- double *array;
qsort 함수는 "퀵 소트(quick sort)" 알고리즘을 사용해서 동작한다는 사실에 기인하여 qsort라는 이름이 유래되었다.
15. 4 탐색과 정렬의 예
이곳에서는 구조체의 배열에 qsort 와 bsearch를 사용하는 예를 보여주고 있다. 배열의 오브젝트들은 strcmp 함수를 사용해서 그들의 이름을 비교함으로써 정렬되어졌다.
그러면, 우리는 그들의 이름에 기초한 개개의 오브젝트들을 살펴볼 수 있다.
- #include <stdlib. h>
- #include <stdio. h>
- #include <string. h>
- /* 정렬할 critter들의 배열을 정의하라. */
- struct critter
- {
- const char *name;
- const char *species;
- };
- struct critter muppets[] =
- {
- {"Kermit", "frog"},
- {"Piggy", "pig"},
- {"Gonzo", "whatever"},
- {"Fozzie", "bear"},
- {"Sam", "eagle"},
- {"Robin", "frog"},
- {"Animal", "animal"},
- {"Camilla", "chicken"},
- {"Sweetums", "monster"},
- {"Dr. Strangepork", "pig"},
- {"Link Hogthrob", "pig"},
- {"Zoot", "human"},
- {"Dr. Bunsen Honeydew", "human"},
- {"Beaker", "human"},
- {"Swedish Chef", "human"}
- {"Piggy", "pig"},
- };
- int count = sizeof (muppets) / sizeof (struct critter);
- /* 이것은 정렬과 탐색을 위해 사용하는 비교함수이다. */
- int
- critter_cmp (const struct critter *c1, const struct critter *c2)
- {
- return strcmp (c1->name, c2->name);
- }
- /* critter에 대한 정보를 프린트하라. */
- void
- print_critter (const struct critter *c)
- {
- printf ("%s, the %s\n", c->name, c->species);
- }
- /* 정렬된 배열을 살펴보라 */
- void
- find_critter (const char *name)
- {
- struct critter target, *result;
- target. name = name;
- result = bsearch(&target, muppets, count, sizeof (struct critter), critter_cmp);
- if (result)
- print_critter (result);
- else
- printf ("Couldn't find %s. \n", name);
- target. name = name;
- }
- /* Main 함수 */
- int
- main (void)
- {
- int i;
- for (i = 0; i < count; i++)
- print_critter (&muppets[i]);
- printf ("\n");
- qsort (muppets, count, sizeof (struct critter), critter_cmp);
- for (i = 0; i < count; i++)
- print_critter (&muppets[i]);
- printf ("\n");
- find_critter ("Kermit");
- find_critter ("Gonzo");
- find_critter ("Janice");
- return 0;
- }
- #include <stdio. h>
- 이 프로그램의 출력은 다음과 같다.
- Kermit, the frog
- Piggy, the pig
- Gonzo, the whatever
- Fozzie, the bear
- Sam, the eagle
- Robin, the frog
- Animal, the animal
- Camilla, the chicken
- Sweetums, the monster
- Dr. Strangepork, the pig
- Link Hogthrob, the pig
- Zoot, the human
- Dr. Bunsen Honeydew, the human
- Beaker, the human
- Swedish Chef, the human
- Animal, the animal
- Beaker, the human
- Camilla, the chicken
- Dr. Bunsen Honeydew, the human
- Dr. Strangepork, the pig
- Fozzie, the bear
- Gonzo, the whatever
- Kermit, the frog
- Link Hogthrob, the pig
- Piggy, the pig
- Robin, the frog
- Sam, the eagle
- Swedish Chef, the human
- Sweetums, the monster
- Zoot, the human
- Kermit, the frog
- Gonzo, the whatever
- Couldn't find Janice.