Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.56/34: Рейтинг темы: голосов - 34, средняя оценка - 4.56
61 / 28 / 24
Регистрация: 28.09.2017
Сообщений: 399

Бинарный поиск без предварительной сортировки

16.03.2018, 14:25. Показов 7190. Ответов 45
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем привет! Мне надо организовать двоичный поиск в массиве, но он не отсортирован по возрастанию или убыванию.
Вопрос: Как, если это возможно, найти элемент в таком массиве, методом бинарного дерева.
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
16.03.2018, 14:25
Ответы с готовыми решениями:

Бинарный поиск с любым видом сортировки
:: Бинарный поиск Помагите сделать бинарный поиск с любым видом сортировки?

Если заменить только один процессор, загрузится ли система без всякой предварительной подготовки?
Конечно знаю правила про перенос системы и подготовки, для перехода на новое железо. Но тем не менее интересно, если тупо заменить только...

Можно ли загрузить модели, текстуры и прочий контент без предварительной их компиляции с помощью ContentPipeline
Можно ли загрузить меши (модели), текстуры и прочий контент без предварительной их компиляции с помощью ContentPipeline? Речь идет,...

45
 Аватар для QuakerRUS
1469 / 1010 / 456
Регистрация: 30.10.2017
Сообщений: 2,799
16.03.2018, 16:11
Студворк — интернет-сервис помощи студентам
pavel2210057, через дерево не придется. Оно уже хранится в памяти сортированным. Новое значение в дерево добавляется практически моментально.
0
61 / 28 / 24
Регистрация: 28.09.2017
Сообщений: 399
16.03.2018, 16:13  [ТС]
QuakerRUS, я о таком просто еще не слышал, можете показать на простом примере, пожалуйста.

Добавлено через 1 минуту
Вы меня заинтересовали
0
 Аватар для QuakerRUS
1469 / 1010 / 456
Регистрация: 30.10.2017
Сообщений: 2,799
16.03.2018, 16:26
pavel2210057, вот с этим у меня сложности. У меня есть старенькая программа, которую я писал с примера в древней книге под древний компилятор. А вот на VS2017 она у меня не компилируется с моими правками, возможно что то в стандарте отличается. Что именно, я пока понять не могу. Но для наглядного примера возможно подойдет. Неизмененный код:

C++
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
// TREENODE.H:      Определение класса TreeNode
#ifndef TREENODE_H
#define TREENODE_H
 
template<class NODETYPE>
class TreeNode
{
    friend class Tree<NODETYPE>;
 
public:
    TreeNode(const NODETYPE &);     // конструктор
    NODETYPE getData() const;       // возвращение данных
 
private:
    TreeNode * leftPtr;             // указатель на левое поддерево
    NODETYPE data;
    TreeNode *rightPtr;             // указатель на правое поддерево
};
 
// Конструктор
template<class NODETYPE>
TreeNode<NODETYPE>::TreeNode(const NODETYPE &d)
{
    data = d;
    leftPtr = rightPtr = 0;
}
 
// Возвращение копии значений данных
template<class NODETYPE>
NODETYPE TreeNode<NODETYPE>::getData() const
{
    return data;
}
 
#endif
 
// TREE.H:          Определение шаблона класса Tree
#ifndef TREE_H
#define TREE_H
 
#include <iostream.h>
#include <assert.h>
#include "treenode.h"
 
template<class NODETYPE>
class Tree
{
public:
    Tree();
    ~Tree();
    void insertNode(const NODETYPE &);
    void preOrderTraversal() const;
    void inOrderTraversal() const;
    void postOrderTraversal() const;
 
private:
    TreeNode<NODETYPE> *rootPtr;
 
    // функции утилиты
    void insertNodeHelper(TreeNode<NODETYPE> **, const NODETYPE &);
    void preOrderHelper(TreeNode<NODETYPE> *) const;
    void inOrderHelper(TreeNode<NODETYPE> *) const;
    void postOrderHelper(TreeNode<NODETYPE> *) const;
    void deconstructorHelper(TreeNode<NODETYPE> *) const;
};
 
template<class NODETYPE>
Tree<NODETYPE>::Tree()
{
    rootPtr = 0;
}
 
template<class NODETYPE>
Tree<NODETYPE>::~Tree()
{
    deconstructorHelper(rootPtr);
}
 
template<class NODETYPE>
void Tree<NODETYPE>::insertNode(const NODETYPE &value)
{
    insertNodeHelper(&rootPtr, value);
}
 
// Эта функция принимает указатель на указатель, так что указатель может быть
// модифицирован
template<class NODETYPE>
void Tree<NODETYPE>::insertNodeHelper(TreeNode<NODETYPE> **ptr,
    const NODETYPE &value)
{
    if (*ptr == 0)                  // пустое дерево
    {
        *ptr = new TreeNode<NODETYPE>(value);
        assert(*ptr != 0);
    }
    else                            // дерево не пустое
    {
        if (value < (*ptr)->data)
            insertNodeHelper(&((*ptr)->leftPtr), value);
        else
            insertNodeHelper(&((*ptr)->rightPtr), value);
    }
}
 
template<class NODETYPE>
void Tree<NODETYPE>::preOrderTraversal() const
{
    preOrderHelper(rootPtr);
    cout << endl;
}
 
template<class NODETYPE>
void Tree<NODETYPE>::preOrderHelper(TreeNode<NODETYPE> *ptr) const
{
    if (ptr != 0)
    {
        cout << ptr->data << ' ';
        preOrderHelper(ptr->leftPtr);
        preOrderHelper(ptr->rightPtr);
    }
}
 
template<class NODETYPE>
void Tree<NODETYPE>::inOrderTraversal() const
{
    inOrderHelper(rootPtr);
    cout << endl;
}
 
template<class NODETYPE>
void Tree<NODETYPE>::inOrderHelper(TreeNode<NODETYPE> *ptr) const
{
    if (ptr != 0)
    {
        inOrderHelper(ptr->leftPtr);
        cout << ptr->data << ' ';
        inOrderHelper(ptr->rightPtr);
    }
}
 
template<class NODETYPE>
void Tree<NODETYPE>::postOrderTraversal() const
{
    postOrderHelper(rootPtr);
    cout << endl;
}
 
template<class NODETYPE>
void Tree<NODETYPE>::postOrderHelper(TreeNode<NODETYPE> *ptr) const
{
    if (ptr != 0)
    {
        postOrderHelper(ptr->leftPtr);
        postOrderHelper(ptr->rightPtr);
        cout << ptr->data << ' ';
    }
}
 
template<class NODETYPE>
void Tree<NODETYPE>::deconstructorHelper(TreeNode<NODETYPE> *ptr) const
{
    if (ptr != 0)
    {
        deconstructorHelper(ptr->leftPtr);
        deconstructorHelper(ptr->rightPtr);
        delete ptr;
    }
}
 
#endif
 
// Упражнение 15.16
//
 
#include <iostream.h>
#include <iomanip.h>
#include "tree.h"
 
int main()
{
    Tree<int> intTree;
    int intVal;
 
    cout << endl << "Введите 10 целых чисел: " << endl;
 
    for (int i = 0; i < 10; i++)
    {
        cin >> intVal;
        intTree.insertNode(intVal);
    }
 
    cout << endl << "Обход в ширину" << endl;
    intTree.preOrderTraversal();
    cout << "Последовательный обход" << endl;
    intTree.inOrderTraversal();
    cout << "Обратный обход" << endl;
    intTree.postOrderTraversal();
 
    Tree<float> floatTree;
    float floatVal;
 
    cout << endl << "Введите 10 чисел с плавающей точкой:" << endl
        << setiosflags(ios::fixed | ios::showpoint) << setprecision(1);
 
    for (int i = 0; i < 10; i++)
    {
        cin >> floatVal;
        floatTree.insertNode(floatVal);
    }
 
    cout << endl << "Обход в ширину" << endl;
    floatTree.preOrderTraversal();
    cout << "Последовательный обход" << endl;
    floatTree.inOrderTraversal();
    cout << "Обратный обход" << endl;
    floatTree.postOrderTraversal();
 
    return 0;
}
Добавлено через 1 минуту
pavel2210057, как вариант, можете поискать в сети готовые решения или воспользоваться какой-нибудь библиотекой, которая работает с деревьями.
1
61 / 28 / 24
Регистрация: 28.09.2017
Сообщений: 399
16.03.2018, 16:32  [ТС]
QuakerRUS, спасибо, позже почитаю ваш код и пошарюсь в инете на эту тему, спасибо вам
0
677 / 479 / 216
Регистрация: 06.09.2013
Сообщений: 1,312
16.03.2018, 16:34
Цитата Сообщение от QuakerRUS Посмотреть сообщение
Ради интереса создал массив на 1000000 рандомных строк, отсортировал его через std::sort(), добавил к нему новое значение и еще раз запустил сортировку.
Так при добавлении нового пересортировывать не надо, нужно найти место нового элемента бинарным поиском и вставить его туды.
Что касается дерева, то его же балансировать надо при вставке-удалении, если заранее распределение значений элементов неизвестно, иначе перекос на одну ветвь будет и время поиска станет линейным.
0
61 / 28 / 24
Регистрация: 28.09.2017
Сообщений: 399
16.03.2018, 16:37  [ТС]
woldemas, какой способ лучший по-вашему?
0
677 / 479 / 216
Регистрация: 06.09.2013
Сообщений: 1,312
16.03.2018, 16:42
pavel2210057, а я не понял, что вам надо.
Быстро искать элемент и в тоже время важен порядок следования элементов в исходном массиве?
0
61 / 28 / 24
Регистрация: 28.09.2017
Сообщений: 399
16.03.2018, 16:43  [ТС]
woldemas, верно
0
 Аватар для QuakerRUS
1469 / 1010 / 456
Регистрация: 30.10.2017
Сообщений: 2,799
16.03.2018, 16:48
woldemas, даже если через insert вставить, нужно сдвинуть миллион значений. У меня заняло примерно секунду процессорного времени, а это тоже немало.

Цитата Сообщение от woldemas Посмотреть сообщение
Что касается дерева, то его же балансировать надо при вставке-удалении, если заранее распределение значений элементов неизвестно, иначе перекос на одну ветвь будет и время поиска станет линейным.
Смотря как идет распределение значений. Если они будут по возрастанию или убыванию поступать, то это критично скажется на производительности. Если более-менее равномерно, то балансировать дерево можно в любой момент времени при такой необходимости.
0
677 / 479 / 216
Регистрация: 06.09.2013
Сообщений: 1,312
16.03.2018, 16:53
pavel2210057, мне кажется надо задачу пересмотреть.
Но в такой постановке, я бы хранил два массива и при добавлении вставлял в отсортированный на нужное место через бинарный поиск, и дописывал в конец не отсортированного.

Добавлено через 2 минуты
Цитата Сообщение от QuakerRUS Посмотреть сообщение
Смотря как идет распределение значений. Если они будут по возрастанию или убыванию поступать, то это критично скажется на производительности. Если более-менее равномерно, то балансировать дерево можно в любой момент времени при такой необходимости.
Так я про то и писал.
Цитата Сообщение от QuakerRUS Посмотреть сообщение
даже если через insert вставить, нужно сдвинуть миллион значений.
Согласен, но все ж это не сортировка. Можно что-нибудь придумать, наверное, какой нибудь связный список из блоков равной длины.
0
 Аватар для Новичок
1682 / 1098 / 489
Регистрация: 17.07.2012
Сообщений: 5,361
16.03.2018, 17:03
Цитата Сообщение от woldemas Посмотреть сообщение
я бы хранил два массива и при добавлении вставлял в отсортированный на нужное место через бинарный поиск
Какой смысл? Вставка все равно линейное время занимает, бинарный поиск не поможет.
Вообще я совсем не понимаю что нужно автору. Если тупо найти элемент в массиве, то быстрее конечно же линейный поиск чем сортировка + бинарный поиск(это очевидно). Если надо быстро вставлять новые элементы и чтоб они шли по порядку тогда бинарное дерево поиска. Но чтоб дерево работало быстро, оно должно быть сбалансированным. Можно свое закодить(КЧ-дерево, АВЛ-дерево), а можно воспользоваться готовым из стандартной библиотеки std::set / std::multiset / std::map в зависимости от задачи.
0
 Аватар для QuakerRUS
1469 / 1010 / 456
Регистрация: 30.10.2017
Сообщений: 2,799
16.03.2018, 17:07
Цитата Сообщение от Новичок Посмотреть сообщение
Если тупо найти элемент в массиве, то быстрее конечно же линейный поиск чем сортировка + бинарный поиск(это очевидно)
Зачем перед каждым поиском сортировать массив? Только в том случае, если он еще не сортированный на момент необходимости поиска.

А так согласен, данных мало, непонятно, что автору именно надо, так как он спрашивает теоретические вопросы, а практическую задачу не озвучивает. Сколько будет добавлений данных в секунду? Сколько будет поисков в секунду? Надо и плясать уже от этого, какой вариант выбирать.
0
 Аватар для Новичок
1682 / 1098 / 489
Регистрация: 17.07.2012
Сообщений: 5,361
16.03.2018, 17:21
Цитата Сообщение от QuakerRUS Посмотреть сообщение
Зачем перед каждым поиском сортировать массив? Только в том случае, если он еще не сортированный на момент необходимости поиска.
Т.е для реализации быстрого поиска вы все-таки предлагаете сортировать???

Добавлено через 3 минуты
Если мы только один раз добавим кучу элементов, а потом будут запросы только на поиск, то отсортировать в принципе хороший вариант. Короче надо все-таки чтоб ТС нормально объяснил что ему надо.
0
 Аватар для QuakerRUS
1469 / 1010 / 456
Регистрация: 30.10.2017
Сообщений: 2,799
16.03.2018, 17:25
Новичок, я лишь указал на то, что одна сортировка+много бинарных поисков будут работать быстрее, чем много линейных поисков. А так я за дерево бинарное топлю. Но если данные будут поступать упорядоченно, дерево будет не такое эффективное, как хотелось бы. Но думаю не менее эффективным чем линейный поиск все же.
0
 Аватар для Новичок
1682 / 1098 / 489
Регистрация: 17.07.2012
Сообщений: 5,361
16.03.2018, 17:35
Цитата Сообщение от QuakerRUS Посмотреть сообщение
Новичок, я лишь указал на то, что одна сортировка+много бинарных поисков будут работать быстрее, чем много линейных поисков.
Это да. Мне просто сначала показалось что вы предлагаете каждый раз сортировать и применять бинарный поиск, потому что новые элементы могли добавиться. Но в таком случае только бинарное дерево поиска / хеш-таблица.

Добавлено через 55 секунд
Цитата Сообщение от QuakerRUS Посмотреть сообщение
Но если данные будут поступать упорядоченно, дерево будет не такое эффективное, как хотелось бы.
Есть же сбалансированные деревья. Правда реализация их непростая. Потому проще воспользоваться стандартной библиотекой.
0
677 / 479 / 216
Регистрация: 06.09.2013
Сообщений: 1,312
16.03.2018, 17:39
Цитата Сообщение от Новичок Посмотреть сообщение
Какой смысл? Вставка все равно линейное время занимает, бинарный поиск не поможет.
Смысл только, если поиск выполняется очень часто, а вставка редко. Мне почему-то кажется, что такой вариант на практике чаще встречается, хотя кто его знает, что там у ТС происходит.
0
 Аватар для QuakerRUS
1469 / 1010 / 456
Регистрация: 30.10.2017
Сообщений: 2,799
16.03.2018, 17:42
Новичок, да, мы выше уже это обсуждали. И тут опять-таки зависит от постановки задачи. Если данные постоянно будут поступать упорядоченно, придется дерево постоянно балансировать. Правда это очень теоретический случай, поэтому я и предлагал дерево.
0
 Аватар для Новичок
1682 / 1098 / 489
Регистрация: 17.07.2012
Сообщений: 5,361
16.03.2018, 17:47
Цитата Сообщение от QuakerRUS Посмотреть сообщение
Если данные постоянно будут поступать упорядоченно, придется дерево постоянно балансировать.
std::set сам все сделает. За логарифм.
0
 Аватар для QuakerRUS
1469 / 1010 / 456
Регистрация: 30.10.2017
Сообщений: 2,799
16.03.2018, 17:51
Новичок, сделать то сделает, но сколько он ресурсов будет на это тратить?
0
322 / 174 / 78
Регистрация: 09.10.2014
Сообщений: 809
16.03.2018, 17:52
Всегда интересовал этот вопрос. Что если использовать std::vector для сохранения структуры, std::set для поиска и std::shared_ptr?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
16.03.2018, 17:52

Поиск заданного элемента в упорядоченном массиве(бинарный поиск)
Заполнить одномерный массив из n элементов по формуле приведенной в картинке. Размерность массива задать в виде именованной константы....

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

Поиск заданного элемента в упорядоченном массиве (бинарный поиск)
Заполнить одномерный массив из n элементов согласно таблицы. Размерность массива задать в виде именованной константы. Вывести массив на...

Поиск числа в двумерном массиве (бинарный поиск)
Произвожу поиск элемента в массиве двумя способами: линейным(последовательным) поиском и бинарным(двоичным). Первый работает на ура. Второй...

Поиск перебором или бинарный поиск в StringGrid
как реализовать поиск в stringgrid (поиск перебором или бинарный поиск)? напр.задаешь в edit.text что искать и stringgrid выводит только...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
Сезонность закисления почв
anaschu 04.07.2026
200 часов это все равно моловато. Есть ситуации, но нестандартные, когда смена происходит за 5 лет. Но обычно это 50 лет и более. Наверное, закисление почвы происходит сезонно в средней. . .
В чем ценность человеческого опыта в глобальном смысле?
kumehtar 03.07.2026
Возможно, ценность человека не в том, что он однажды достигает мудрости, а в том, что он становится носителем карты пути. Он знает не только истину, но и последовательность внутренних изменений,. . .
интеграция AnyLogic с самописным REST API и переход на Odoo
anaschu 03.07.2026
Успешная интеграция AnyLogic с самописным REST API и переход на промышленную Odoo WMS Сегодня проделал огромный путь от простой симуляции физических процессов до построения полноценной. . .
Поиск всех путей на ориентированном графе. Linux
dcc0 02.07.2026
Переработка старого кода из моей статьи. Через несколько переработок от PHP кода к C89 (надеюсь, 89). Но довольно запутанно получилось. Код для Linux. Но если убрать time и то, что с ним. . .
Сам себя обучал rest api
anaschu 02.07.2026
Педагогический лайфхак: Почему чистый REST API для ученика намного круче, чем готовые библиотеки Когда мы отказались от капризного JAR-файла AnyLogic и переписали код на стандартный HttpClient,. . .
rest api anylogic - выполнение модели на своём русском сайте
anaschu 02.07.2026
Как подружиться с AnyLogic Cloud API, победить провайдеров и развернуться Java-бэкенд в Docker на бесплатном хостинге: Двухдневный лог борьбы Всем привет! Хочу поделиться свежим (и довольно. . .
Где деньги лежат
kumehtar 02.07.2026
Это - японская подводная лодка I-52 (тип C2, кодовое имя Momi) вышла из Японии в марте 1944 года с миссией в оккупированную немцами Францию (Лорьян). Это была одна из «Янаги»-миссий по обмену. . .
Krabik для WoW 3.3.5a, многоязычный
AmbA 02.07.2026
Допилил бота, думаю что окончательно. Изменения: - добавлена многоязычность - добавлено снятие скриншотов - добавлено поддержание бафов хождения по воде (для жреца, дк и шамана) - и так, по. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru