Чтение онлайн

на главную - закладки

Жанры

Linux программирование в примерах
Шрифт:

2097332 06-generall.texi

...

6.2.2. Бинарный поиск:

bsearch

Линейный поиск в значительной степени похож на свое название: вы начинаете в начале и проходите искомый массив, пока не встретите то, что нужно. Для чего-нибудь простого, типа поиска целых, это обычно принимает форму цикла

for
. Рассмотрите эту функцию:

/* ifind --- линейный поиск, возвращает найденный индекс или -1 */

int ifind(int x, const int array[], size_t nelems) {

 size_t i;

 for (i = 0; i < nelems; i++)

if (array(i) == x) /* найдено */

return i;

 return -1;

}

Преимуществом линейного поиска является его простота; легко с самого начала написать правильный код. Более того, он работает всегда. Даже если в конец массива добавляются элементы или они удаляются из него, нет необходимости сортировать массив.

Недостатком линейного поиска является то, что он медленный. В среднем для массива, содержащего

nelems
элементов, при линейном поиске случайного элемента требуется '
nelems/2
' сравнений, прежде чем найдется нужный элемент. Это становится чрезмерно дорогим даже на современных высокопроизводительных системах, когда
nelems
принимает большие значения. Поэтому линейный поиск следует использовать лишь с небольшими массивами.

В отличие от линейного, бинарный поиск требует, чтобы входной массив был уже отсортирован. Недостатком здесь является то, что если добавляются элементы, массив перед новым поиском нужно повторно отсортировать. (Когда элементы удаляются, остальное содержимое массива все равно должно быть перетасовано. Это не так дорого, как повторная сортировка, но все равно может потребовать большого перемещения данных.)

Преимуществом бинарного поиска, и значительным, является то, что бинарный поиск умопомрачительно быстр, требуя самое большее log2(N) сравнений, где N является числом элементов в массиве. Функция

bsearch
объявлена следующим образом:

#include <stdlib.h> /* ISO С */

void *bsearch(const void *key, const void *base, size_t nmemb,

 size_t size, int (*compare)(const void*, const void*));

Параметры и их назначение сходны с таковыми для

qsort
:

const void *key

Объект, который ищется в массиве.

const void *base

Начало массива.

size_t nmemb

Число элементов в массиве.

size_t size

Размер каждого элемента, полученный с помощью

sizeof
.

int (*compare)(const void*, const void*)

Функция сравнения. Она должна работать таким же образом, как функция сравнения для

qsort
, возвращая отрицательные/нулевые/положительные значения в соответствии с тем, меньше/равен/больше первый параметр по сравнению со вторым.

Если объект не найден,

bsearch
возвращает
NULL
. В противном случае она возвращает указатель на найденный объект. Если
key
соответствует более одного объекта, какой из них будет возвращен, не определено. Поэтому, как и в случае с
qsort
, убедитесь, что функция сравнения принимает во внимание все существенные части искомой структуры данных.

ch06-searchemp.c
показывает
bsearch
на практике, расширяя использованный ранее пример
struct employee
:

1 /* ch06-searchemp.с ---- Демонстрация bsearch. */

2

3 #include <stdio.h>

4 #include <errno.h>

5 #include <stdlib.h>

6

7 struct employee {

8 char lastname[30];

9 char firstname[30];

10 long emp_id;

11 time_t start_date;

12 };

13

14 /* emp_id_compare --- сравнение по ID */

15

16 int emp_id_compare(const void *e1p, const void *e2p)

17 {

18 const struct employee *e1, *e2;

19

20 e1 = (const struct employee*)e1p;

21 e2 = (const struct employee*)e2p;

22

23 if (e1->emp_id < e2->emp_id)

24 return -1;

25 else if (e1->emp_id == e2->emp_id)

26 return 0;

27 else

28 return 1;

29 }

30

31 /* print_employee --- напечатать структуру сотрудника */

32

33 void print_employee(const struct employee *emp)

34 {

35 printf("%s %s\t%d\t%s", emp->lastname, emp->firstname,

36 emp->emp_id, ctime(&emp->start_date));

37 }

Строки 7–12 определяют

struct employee
; она та же, что и раньше. Строки 16–29 служат в качестве функции сравнения как для
qsort
, так и для
bsearch
. Они сравнивают лишь ID сотрудников. Строки 33–37 определяют
print_employee
, которая является удобной функцией для печати структуры, поскольку это делается из разных мест.

39 /* main --- демонстрация сортировки */

Поделиться:
Популярные книги

Чужак из ниоткуда 2

Евтушенко Алексей Анатольевич
2. Чужак из ниоткуда
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Чужак из ниоткуда 2

Когда он был порочным

Куин Джулия
6. Бриджертоны
Любовные романы:
исторические любовные романы
8.85
рейтинг книги
Когда он был порочным

На границе империй. Том 10. Часть 3

INDIGO
Вселенная EVE Online
Фантастика:
боевая фантастика
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 10. Часть 3

Наследие Маозари 3

Панежин Евгений
3. Наследие Маозари
Фантастика:
рпг
аниме
5.00
рейтинг книги
Наследие Маозари 3

Стеллар. Заклинатель

Прокофьев Роман Юрьевич
3. Стеллар
Фантастика:
боевая фантастика
8.40
рейтинг книги
Стеллар. Заклинатель

Последний Паладин

Саваровский Роман
1. Путь Паладина
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Последний Паладин

Второгодка. Книга 2. Око за око

Ромов Дмитрий
2. Второгодка
Фантастика:
героическая фантастика
альтернативная история
фэнтези
5.00
рейтинг книги
Второгодка. Книга 2. Око за око

Родословная. Том 3

Ткачев Андрей Юрьевич
3. Линия крови
Фантастика:
городское фэнтези
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Родословная. Том 3

Кодекс Охотника. Книга XII

Винокуров Юрий
12. Кодекс Охотника
Фантастика:
боевая фантастика
городское фэнтези
аниме
7.50
рейтинг книги
Кодекс Охотника. Книга XII

Я снова не князь! Книга XVII

Дрейк Сириус
17. Дорогой барон!
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Я снова не князь! Книга XVII

Журнал «Если», 2002 № 08

Андерсон Кевин Джей
114. Журнал Если
Фантастика:
научная фантастика
5.00
рейтинг книги
Журнал «Если», 2002 № 08

Газлайтер. Том 5

Володин Григорий
5. История Телепата
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Газлайтер. Том 5

#Бояръ-Аниме. Газлайтер. Том 11

Володин Григорий Григорьевич
11. История Телепата
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
#Бояръ-Аниме. Газлайтер. Том 11

Последний Паладин. Том 4

Саваровский Роман
4. Путь Паладина
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Последний Паладин. Том 4