powered by simpleCommunicator - 2.0.59     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Программирование [игнор отключен] [закрыт для гостей] / Бинарный поиск в С
39 сообщений из 39, показаны все 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
Бинарный поиск в С
    #39540933
Vladimir Baskakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
jenya7MBojenya7,

какое ещё условие нужно?
спасибо. сделал так
Код: 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;
    }
}


похоже что работает.
....................................
а я бы возвращал положительное число, индекс+1 если найдено, а если не найдено - отрицательный индекс вставки - и параметр found тогда не нужен.

А чего изобретаете то? или так, язык поучить?
...
Рейтинг: 0 / 0
Бинарный поиск в С
    #39540940
Vladimir Baskakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
плохо сказал.
можно задачу ф-ции переформулировать так - найти индекс первого элемента, который больше или равен ключу.

Тогда вызывающая сторона сможет посмотреть - если ей вернули -1 - вставлять в конец,
если ноль и больше - посмотреть что лежит на этом месте - ключ - значит нашлось, не ключ - тогда это место вставки.

параметр found точно не нужен.
...
Рейтинг: 0 / 0
Бинарный поиск в С
    #39541047
jenya7
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
[quot Vladimir Baskakov]jenya7пропущено...


....................................
а я бы возвращал положительное число, индекс+1 если найдено, а если не найдено - отрицательный индекс вставки - и параметр found тогда не нужен.

А чего изобретаете то? или так, язык поучить?
Задача такая. Есть массив пакетов приходящих по TCP, в принципе не важно откуда они приходят.
Я должен хранить эти пакеты, для этого я создал массив пакетов. Глубина хранения пока 512 хотя может вырасти до пару тысяч, это еще TBD. То есть размер массива пока 512.
В приходящем пакете есть ИД и команда - добавить пакет, удалить пакет, редактировать пакет.
Доступ к пакету должен быть максимально быстрым. Находить ИД пакета простым перебором в for долго. Поэтому решил находить бинарным поиском и если ИД не найден вставлять его на его место, чтоб массив всегда был сортирован по ИД.
...
Рейтинг: 0 / 0
Бинарный поиск в С
    #39541058
jenya7
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
пока что сделал так.
Код: 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.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
#define MESSAGE_SIZE 20
#define MESSAGE_ARR_SIZE  20

typedef struct TEST_MESSAGE_S
{
    int id;
    char data[MESSAGE_SIZE];
}TEST_MESSAGE;

TEST_MESSAGE messages[MESSAGE_ARR_SIZE];

char spectra_packet[20];

int  spectra_id;
int spectra_command;

int BinarySearch(TEST_MESSAGE a[], int pos, int key, int *found);
void InsertElement(int id, char *msg);
void DeleteElement(int id);

int BinarySearch(TEST_MESSAGE 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].id > key) 
    {
        *found = 0;
        return 0;
    }
    else if (a[pos - 1].id < key)
    {
        *found = 0;
        return pos;
    }
    
    while (first < last)
    {
        mid = first + (last - first) / 2;

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

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

void UpdateElement(int id[, char msg[])
{
}

void InsertElement(int id, char *msg)
{
    int idx;
    
    idx = BinarySearch(messages, glob_pos, id, &found);
    
    if (found)  //command NEW but the element exists - issue UPDATE
    {
        UpdateElement(idx, msg);
    }
    else //element not found - add one
    {
        memmove(messages+(idx+1), messages+idx, sizeof(TEST_MESSAGE)*(glob_pos-idx));   //glob_pos-1-idx
        
        messages[idx].id = id;
        memcpy(messages[idx].data, msg, sizeof(spectra_packet));
        
       //if (glob_pos < MESSAGE_ARR_SIZE)
        glob_pos++;
    }
}

void DeleteElement(int id)
{
     int idx;
    
    idx = BinarySearch(messages, glob_pos, id, &found);
    
    if (found) 
    {
       memmove(messages+idx, messages+(idx+1), sizeof(TEST_MESSAGE)*glob_pos-1-idx);
       
       if (glob_pos > 0)
           glob_pos--;
    }
}
...
Рейтинг: 0 / 0
Бинарный поиск в С
    #39541062
jenya7
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
тестирую так
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
 /////////////////////////////TEST  AREA ///////////////////////////////////
  for (idx = 0; idx < 20; idx++)
  {
      messages[idx].id = -1;
  }
  
  while(1)
  {
      spectra_id = spectra_packet[0];
      spectra_command = spectra_packet[1];
      
      switch (spectra_command)
      {
            case 1:
                if (glob_pos < MESSAGE_ARR_SIZE)
                    InsertElement(spectra_id, spectra_packet);
            break;
            case 2:
                DeleteElement(spectra_id);
            break;
      }
  }
/////////////////////////////////////////////////////////////////////



пока вроде вставка и удаление проходят нормально.
...
Рейтинг: 0 / 0
Бинарный поиск в С
    #39541106
Vladimir Baskakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Задача такая. Есть массив пакетов приходящих по TCP, в принципе не важно откуда они приходят.
Я должен хранить эти пакеты, для этого я создал массив пакетов. Глубина хранения пока 512 хотя может вырасти до пару тысяч, это еще TBD. То есть размер массива пока 512.
В приходящем пакете есть ИД и команда - добавить пакет, удалить пакет, редактировать пакет.
Доступ к пакету должен быть максимально быстрым. Находить ИД пакета простым перебором в for долго. Поэтому решил находить бинарным поиском и если ИД не найден вставлять его на его место, чтоб массив всегда был сортирован по ИД.

чисто теоретически,
https://habrahabr.ru/post/65617/
https://ru.wikipedia.org/wiki/B-дерево
есть разные упорядоченные структуры данных для хранения сортированных данных
- всякие бинарные и сбалансированные деревья. может быть среди них поискать.

или - хэш-таблицы. чтобы по целому вычислять ключик, где искать - в каком сегменте, и там уже перебором или бинарным поиском. Мне думается, что хэширование - поможет.

допустим, если храним 2000 значений - захешировали на сотню, и вот уже в каждом массивчике перебираемых 20 единиц (в среднем) - и вставлять быстро и искать нормально. А перерасход памяти для такого количества значений - мизернейший.


============================
всего доброго.

PS
а почему си, а не с++ с огромным массивом оптимизированных уже библиотек? ну дело хозяйское, в целом.
...
Рейтинг: 0 / 0
Бинарный поиск в С
    #39541245
jenya7
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Vladimir BaskakovЗадача такая. Есть массив пакетов приходящих по TCP, в принципе не важно откуда они приходят.
Я должен хранить эти пакеты, для этого я создал массив пакетов. Глубина хранения пока 512 хотя может вырасти до пару тысяч, это еще TBD. То есть размер массива пока 512.
В приходящем пакете есть ИД и команда - добавить пакет, удалить пакет, редактировать пакет.
Доступ к пакету должен быть максимально быстрым. Находить ИД пакета простым перебором в for долго. Поэтому решил находить бинарным поиском и если ИД не найден вставлять его на его место, чтоб массив всегда был сортирован по ИД.

чисто теоретически,
https://habrahabr.ru/post/65617/
https://ru.wikipedia.org/wiki/B-дерево
есть разные упорядоченные структуры данных для хранения сортированных данных
- всякие бинарные и сбалансированные деревья. может быть среди них поискать.

или - хэш-таблицы. чтобы по целому вычислять ключик, где искать - в каком сегменте, и там уже перебором или бинарным поиском. Мне думается, что хэширование - поможет.

допустим, если храним 2000 значений - захешировали на сотню, и вот уже в каждом массивчике перебираемых 20 единиц (в среднем) - и вставлять быстро и искать нормально. А перерасход памяти для такого количества значений - мизернейший.


============================
всего доброго.

PS
а почему си, а не с++ с огромным массивом оптимизированных уже библиотек? ну дело хозяйское, в целом.
я думал про хэш. но пока остановились на бинарном поиске.
...
Рейтинг: 0 / 0
Бинарный поиск в С
    #39541255
Vladimir Baskakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
а почему? может быть на макете сверить производительность?

от целого хэш-функция на 10 000 значений посчитается практически влет, и скорее всего в каждом из этих 10000 массивов будет сидеть ну три, ну пять ключей. если всего значений 2000.

Хэширование даст заметно - лучшее масштабирование при увеличении кол-ва эл-тов, сокращая расходы на вставку - меньше памяти надо двигать. ну конечно по ситуации - если код для микроконтроллера - это одно, а если для машинки с кучей памяти под современной осью - совсем другое.

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

от целого хэш-функция на 10 000 значений посчитается практически влет, и скорее всего в каждом из этих 10000 массивов будет сидеть ну три, ну пять ключей. если всего значений 2000.

Хэширование даст заметно - лучшее масштабирование при увеличении кол-ва эл-тов, сокращая расходы на вставку - меньше памяти надо двигать. ну конечно по ситуации - если код для микроконтроллера - это одно, а если для машинки с кучей памяти под современной осью - совсем другое.

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

char * strchr( const char * string, int symbol);

вроде бы эффективно задействует возможности процессора для поиска в области памяти.
вроде бы scas http://programm.ws/page.php?id=129

может быть не сортировать, а искать на уровне байт? найти первый байт искомого числа. проверить совпадение следующих.

мне кажется тут есть о чем подумать, если уж надо очень, очень быстро искать в сравнительно-небольших массивах, до 10-20 килобайт

вплоть до того, что весь массив в котором ищем держать в строковом виде 16-ричных чисел и искать там строковыми, высокооптимизированными ф-циями, которые были и есть в составе стандартной б-ки Си.

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

Попробуйте, шутки ради, вдруг да выйдет....
...
Рейтинг: 0 / 0
Бинарный поиск в С
    #39541270
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
jenya7я думал про хэш. но пока остановились на бинарном поиске.
Тут выбор между быстро искать и и быстро вставлять/удалять. Бинарный поиск ищет достаточно быстро, не факт что хэштаблица будет искать быстрее при нескольких тысячах элементов. Но вставка/удаление требует сдвига существенной части массива, что не быстро.
Если вставок/удалений относительно немного, то твой способ будет нормально работать. Надо просто затестить с нагрузкой похожей на реальную. Если производительность устроит, то можешь оставить как есть.
...
Рейтинг: 0 / 0
Бинарный поиск в С
    #39541274
Vladimir Baskakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
jenya7я представил две опции. но народ выбрал бинарный поиск. я не стал спорить. если будем терять пакеты попробуем хэш. есть еще красно-черное дерево которое, как говорят, на больших массивах дает хорошие результаты.

а время то меряли? профилировали? может и не пробежка по несортированному массиву его занимает? а какая-то предобработка, принятие пакетов, или постобработка?

ну, я против народа то не пойду.... народ сказал, значит так надо.
...
Рейтинг: 0 / 0
Бинарный поиск в С
    #39541276
Vladimir Baskakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima Tjenya7я думал про хэш. но пока остановились на бинарном поиске.
Тут выбор между быстро искать и и быстро вставлять/удалять. Бинарный поиск ищет достаточно быстро, не факт что хэштаблица будет искать быстрее при нескольких тысячах элементов. Но вставка/удаление требует сдвига существенной части массива, что не быстро.
Если вставок/удалений относительно немного, то твой способ будет нормально работать. Надо просто затестить с нагрузкой похожей на реальную. Если производительность устроит, то можешь оставить как есть.

вот и я к тому, что надо понять где затыки сейчас, и где они могут быть, а уж потом выбор выбирать.

(шутка) надеюсь, это курсовичок, а не атомный ледокол с горячей заменой кода на проде. когда бесконечный цикл не даст опустить графитовый стерженек....( конец шутки)
...
Рейтинг: 0 / 0
Бинарный поиск в С
    #39541347
Siemargl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Vladimir Baskakov,

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


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