powered by simpleCommunicator - 2.0.59     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Программирование [игнор отключен] [закрыт для гостей] / Бинарный поиск в С
25 сообщений из 39, страница 1 из 2
Бинарный поиск в С
    #39540282
jenya7
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Я хочу сделать бинарный поиск в сортированном массиве. Без рекурсии.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
int BinarySearch(int arr[], int low, int high, int key)
{
     int mid; // = (low + high)/2;
     int  done = 0;
     
     if (high < low) 
           return -1;
       
     mid = (low + high)/2;
         
     while (!done)
     {
         if(key==arr[mid])
             return mid;
         else if (key > arr[mid])
             mid = ((mid+1) + high) / 2;
         else if (key < arr[mid])
            mid = (low + (mid-1)) / 2;
     }
     
     return -1;
}



Если искомый элемент (key) есть в массиве (arr) то все нормально, функция возвращает индекс массива. Но если элемента нет в массиве я кручусь все время в цикле (while (!done)).
Я что то никак не соображу по какому условию выйти из цикла.
...
Рейтинг: 0 / 0
Бинарный поиск в С
    #39540293
Vladimir Baskakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Надо сжимать интервал, если он сжался, а ничего не нашлось, тогда ой. шпаргалка под спойлером, лучше не подглядывать, без крайней нужды. а додумать. потому что все несложно. Главное не забыть менять done - а то же там константа, поэтому цикл будет вращаться до конца света.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
int BinarySearch(int arr[], int low, int high, int key)
{
     int mid; // = (low + high)/2;
     int  done = 0;
     
     if (high < low) 
           return -1;
       
         
     while (1)
     {
         mid = (low + high)/2;

         if(key==arr[mid])  return mid;

         if (low==high) return -1;

         if (key > arr[mid])  low = (mid+1) 
         else  high =  (mid-1);
                
     }   
    
}


int BinarySearch_rec(int arr[], int low, int high, int key)
{
     int mid; // = (low + high)/2;
     int  done = 0;
     
     if (high < low) return -1;
       
     mid = (low + high)/2;

     if(key==arr[mid])
             return mid;
     if (low==high) return -1;
     if (key > arr[mid])
             low = (mid+1) ;
     else  high =  (mid-1);
     return BinarySearch_rec(arr, low, high, key);
}

...
Рейтинг: 0 / 0
Бинарный поиск в С
    #39540294
exp98
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
По условию done = y, где у != 0
например внутри цикла
...
Рейтинг: 0 / 0
Бинарный поиск в С
    #39540306
jenya7
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Vladimir BaskakovНадо сжимать интервал, если он сжался, а ничего не нашлось, тогда ой. шпаргалка под спойлером, лучше не подглядывать, без крайней нужды. а додумать. потому что все несложно. Главное не забыть менять done - а то же там константа, поэтому цикл будет вращаться до конца света.

большое спасибо. работает. но у меня тут еще одна проблема. я хочу вставлять элемент если он не найден. то есть я хочу вернуть не -1 а индекс на место которого я хочу вставить элемент. соответсвенно все элементы перед ним я сдвину вправо. как мне модифицировать функцию?
я думал ввести условие
Код: plaintext
1.
 else if (key > arr[mid] && key <  arr[mid+1])


но что то в нем не так.
...
Рейтинг: 0 / 0
Бинарный поиск в С
    #39540314
jenya7
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
а проблема в том что это недостаточное условие. нужен какой то флаг - элемент не найден. но тогда получается нужно делать еще один пробег?
...
Рейтинг: 0 / 0
Бинарный поиск в С
    #39540336
MBo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MBo
Гость
jenya7, пробег делать не надо, достаточно ещё одного сравнения. Вот из Вики:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
 
   while (first < last) {
        size_t mid = first + (last - first) / 2;

        if (x <= a[mid])
            last = mid;
        else
            first = mid + 1;
    }

    /* Если условный оператор if (n == 0) и т.д. в начале опущен -
     * значит, тут раскомментировать!
     */
    if (/* last < n && */ a[last] == x) {
        /* Искомый элемент найден. last - искомый индекс */
        return FOUND(last);
    } else {
        /* Искомый элемент не найден. Но если вам вдруг надо его
         * вставить со сдвигом, то его место - last.
         */
        return NOTFOUND(last);
    }
...
Рейтинг: 0 / 0
Бинарный поиск в С
    #39540339
exp98
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
jenya7, а done чем не флаг? в integer разных значений как грязи весной ...
...
Рейтинг: 0 / 0
Бинарный поиск в С
    #39540345
jenya7
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
MBojenya7, пробег делать не надо, достаточно ещё одного сравнения. Вот из Вики:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
 
   while (first < last) {
        size_t mid = first + (last - first) / 2;

        if (x <= a[mid])
            last = mid;
        else
            first = mid + 1;
    }

    /* Если условный оператор if (n == 0) и т.д. в начале опущен -
     * значит, тут раскомментировать!
     */
    if (/* last < n && */ a[last] == x) {
        /* Искомый элемент найден. last - искомый индекс */
        return FOUND(last);
    } else {
        /* Искомый элемент не найден. Но если вам вдруг надо его
         * вставить со сдвигом, то его место - last.
         */
        return NOTFOUND(last);
    }


а FOUND это что? дефайн?
...
Рейтинг: 0 / 0
Бинарный поиск в С
    #39540349
MBo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MBo
Гость
а FOUND это что? дефайн?
Да, там возвращается структура из двух членов - индекс и boolean признак. Достаточно нелепо.
Варианты:
- изменить прототип, индекс сделать аргументом, а результат - boolean
- возвращать положительный индекс при наличии, отрицательный при отсутствии.
- при использовании исключительно для поиска места для вставки - оставить обычный интерфейс
...
Рейтинг: 0 / 0
Бинарный поиск в С
    #39540350
jenya7
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
а где изменяется n?
...
Рейтинг: 0 / 0
Бинарный поиск в С
    #39540355
jenya7
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
не хватает условия. я могу вывести флаг аргументом наружу

int BinarySearch(int a[], int first, int last, int key, int *found)

но нужно еще одно условие
...
Рейтинг: 0 / 0
Бинарный поиск в С
    #39540356
MBo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MBo
Гость
jenya7, это длина массива, она, в общем-то, не нужна и закомментарена. Код https://ru.wikipedia.org/wiki/Двоичный_поиск
...
Рейтинг: 0 / 0
Бинарный поиск в С
    #39540357
MBo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MBo
Гость
jenya7,

какое ещё условие нужно?
...
Рейтинг: 0 / 0
Бинарный поиск в С
    #39540389
jenya7
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
MBojenya7,

какое ещё условие нужно?
спасибо. сделал так
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
int BinarySearch(int a[], int pos, int key, int *found)
{
    int first = 0;
    int last = pos;
    int mid;
    
    if (pos == 0)  //empty array
    {
        *found = 0;
        return 0;
    }
    else if (a[0] > key) 
    {
        *found = 0;
        return 0;
    }
    else if (a[pos - 1] < key)
    {
        *found = 0;
        return pos;
    }
    
    while (first < last)
    {
        mid = first + (last - first) / 2;

        if (key <= a[mid])
            last = mid;
        else
            first = mid + 1;
    }

    if (a[last] == key)
    {
        *found = 1;
        return last;
    }
    else
    {
        *found = 0;
        return last;
    }
}


похоже что работает.
...
Рейтинг: 0 / 0
Бинарный поиск в С
    #39540405
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
jenya7спасибо. сделал так
Код: plaintext
1.
int BinarySearch(int a[], int pos, int key, int *found)


Я так понимаю found это найдено/не найдено.

Обычно наоборот делают, функция возвращает ошибку, а переменная под результат в параметрах, т.е.
Код: plaintext
1.
int BinarySearch(int a[], int pos, int key, int *result)
...
Рейтинг: 0 / 0
Бинарный поиск в С
    #39540410
Siemargl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
http://www.cplusplus.com/reference/cstdlib/bsearch/

и не надо изобретать
...
Рейтинг: 0 / 0
Бинарный поиск в С
    #39540413
jenya7
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dima Tjenya7спасибо. сделал так
Код: plaintext
1.
int BinarySearch(int a[], int pos, int key, int *found)


Я так понимаю found это найдено/не найдено.

Обычно наоборот делают, функция возвращает ошибку, а переменная под результат в параметрах, т.е.
Код: plaintext
1.
int BinarySearch(int a[], int pos, int key, int *result)


понял. спасибо. переделаю.
...
Рейтинг: 0 / 0
Бинарный поиск в С
    #39540419
jenya7
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Siemargl http://www.cplusplus.com/reference/cstdlib/bsearch/

и не надо изобретать
инетересно но сложно. вопрос что будет compar в моем случае?
...
Рейтинг: 0 / 0
Бинарный поиск в С
    #39540422
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
jenya7Siemargl http://www.cplusplus.com/reference/cstdlib/bsearch/

и не надо изобретать
инетересно но сложно. вопрос что будет compar в моем случае?
Там есть пример кода с твоим случаем, т.е. массивом int.
...
Рейтинг: 0 / 0
Бинарный поиск в С
    #39540435
jenya7
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dima Tjenya7пропущено...

инетересно но сложно. вопрос что будет compar в моем случае?
Там есть пример кода с твоим случаем, т.е. массивом int.

а где тут поиск середины?

Код: plaintext
1.
2.
3.
4.
int compareints (const void * a, const void * b)
{
  return ( *(int*)a - *(int*)b );
}
...
Рейтинг: 0 / 0
Бинарный поиск в С
    #39540441
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
jenya7Dima Tпропущено...

Там есть пример кода с твоим случаем, т.е. массивом int.

а где тут поиск середины?

Код: plaintext
1.
2.
3.
4.
int compareints (const void * a, const void * b)
{
  return ( *(int*)a - *(int*)b );
}


Тут нет поиска середины, т.к. это компаратор, т.е. функция сравнения двух элементов массива.
Сам алгоритм поиска внутри bsearch(), в которую передаются исходные данные, включая компаратор.
...
Рейтинг: 0 / 0
Бинарный поиск в С
    #39540446
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima Tэто компаратор, т.е. функция сравнения двух элементов массива
Неправильно выразился, это функция сравнения значений по двум указателям.
...
Рейтинг: 0 / 0
Бинарный поиск в С
    #39540454
jenya7
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dima Tjenya7пропущено...


а где тут поиск середины?

Код: plaintext
1.
2.
3.
4.
int compareints (const void * a, const void * b)
{
  return ( *(int*)a - *(int*)b );
}


Тут нет поиска середины, т.к. это компаратор, т.е. функция сравнения двух элементов массива.
Сам алгоритм поиска внутри bsearch(), в которую передаются исходные данные, включая компаратор.
а нам нужна эта функция для бинарного поиска? мне кажется я могу передать нулевой указатель в качестве аргумента. все аргументы для поиска присутствуют в bsearch а компаратор как мне кажется лишний элемент.
...
Рейтинг: 0 / 0
Бинарный поиск в С
    #39540468
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
jenya7Dima Tпропущено...

Тут нет поиска середины, т.к. это компаратор, т.е. функция сравнения двух элементов массива.
Сам алгоритм поиска внутри bsearch(), в которую передаются исходные данные, включая компаратор.
а нам нужна эта функция для бинарного поиска? мне кажется я могу передать нулевой указатель в качестве аргумента. все аргументы для поиска присутствуют в bsearch а компаратор как мне кажется лишний элемент.
bsearch() универсальная функция для любых типов, на входе у нее void*. Компаратор нужен для того чтобы правильно сравнить два void*
...
Рейтинг: 0 / 0
Бинарный поиск в С
    #39540488
jenya7
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dima Tjenya7пропущено...

а нам нужна эта функция для бинарного поиска? мне кажется я могу передать нулевой указатель в качестве аргумента. все аргументы для поиска присутствуют в bsearch а компаратор как мне кажется лишний элемент.
bsearch() универсальная функция для любых типов, на входе у нее void*. Компаратор нужен для того чтобы правильно сравнить два void*
понял. спасибо. попробую.
...
Рейтинг: 0 / 0
25 сообщений из 39, страница 1 из 2
Форумы / Программирование [игнор отключен] [закрыт для гостей] / Бинарный поиск в С
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]