www.machinelearningmastery.ru

Машинное обучение, нейронные сети, искусственный интеллект
Header decor

Home

Двоичные деревья: дерево поиска.

Дата публикации Mar 3, 2018

Управляемый подход к поиску стоимости.

Пример из веб-приложения,Вот,

Зачем

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

Вариант А:

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

Этот подход работает, но требует посещения страниц от передней части книги до нужного номера телефона.

В информатике это будет искать из1,2,3..NТак ведет себя поиск в связанном списке.

Представьте себе, был ли номер телефона помещен в середине или в конце телефонной книги. Чтобы найти номер, алгоритм должен сначала проверить все остальные номера в телефонной книге, и никто на самом деле этого не делает с реальной или цифровой телефонной книгой.

Вариант Б:

Обычно люди открывают телефонную книгу где-то посередине и спрашивают: «Номер меньше или больше номера на этой странице?». Если нужный номер меньше, перевернителомотьстраниц слева. Если желаемое число больше, перевернителомотьстраниц вправо.

При таком подходе после каждой итерации поисксущественноближе к решению.

Этот подход сопоставим с тем, какбинарное деревоведет себя,Используя двоичное дерево, любое желаемое число в списке из ста тысяч можетобычноможно найти в шестнадцати итерациях, и этоЗачемдвоичное дерево обеспечивает управляемый подход к поиску значений.

какая

Бинарное дерево, набор объектов, связанных черезслеваа такжеправильноуказатели, делает бинарные сравнения.

Если в дереве нет узлов, входящий узел становитсякореньдерева. В приведенном выше примерекореньдесять.

Теперь обратите внимание на узелслеваизкорень, 5. Пять меньше десяти.

Перейти на один уровень глубже.

Обратите внимание на узелправильноиз пяти, семи. Семь больше пяти, но семь меньше десяти. Семерка была помещена вслеваиз десяти, и кправильноиз пяти

Это двоичное размещение создает очень специфическое подмножество.


Давайте внимательнее посмотрим начтов точкудвоичное дерево делает. Скажем, инженер искал значение восемь в дереве ниже.

Код инженера сначала сравнил бы желаемое значение, восемь, скореньзначение десять. Восемь меньше десяти, поэтому программа переместится кслева, Другими словами, значение восемь никогда не будет вправильноподдерево. Зная, что восьмерка никогда не может быть вправильноПод дерево, инженер может исключить половину возможностей.

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

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

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

Создайте двоичное дерево с помощью веб-приложенияВот,

Как

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

Давайте начнем со структуры узла.

Структура узла имеет целое числовал, это будет хранить номер телефона. Далее структура определяет два указателя,слеваа такжеправильно,для значений меньше или больше, чем узел. Наконец, конструктор объявляется для передачи значений в узел.

структура узла:

struct node {
int val;
node* left;
node* right;
node(int v_) : val(v_), left(NULL), right(NULL) {};
};

Далее давайте предоставим макет для класса BinaryTree.

Закрытый раздел класса содержит: структуру узла, указатель узлакореньи перегруженная функция печати.

Открытый раздел класса содержит: функции для добавления узлов, поиска узлов, печати узлов и конструктора класса.

Обратите внимание, что публичная функция печати не принимает параметры, в отличие от частной функции печати.


Класс BinaryTree (макет):

class BinaryTree {
private:
struct node {
...
};
node* root;
void print(node* temp) {
...
}
public:
void addNode(int v_) {
...
}
int findNodeCount(int v_) {
...
}
void print() {
...
}
BinaryTree() { ... }
};

Теперь давайте сосредоточимся на функции добавления узла, используя итеративный подход.

Сначала код проверяет, есть ликорень Если неткореньсоздать новый узел и назначить этот новый узелкорень,в противном случае начните ходить по дереву с указателем узлаходок.

Затем проверьте, является ли входящее значение меньше или больше, чемУокерценность. Если значение меньше, что-то произойдет наслеваветка. Если значение больше, что-то произойдет направильноветка.

Что именно происходит, если значение меньше? Сначала мы проверим, еслиходункислевауказывает на другой узел или указывает назначение NULL.Еслиходок слевауказывает на другой узел, обновить шAlkerравномуходункислеваи начать процесс заново.

Иначе,ходок слевауказывает назначение NULLи это означает, что алгоритм достиг нижней части дерева. Достижение нижней части дерева также означает, что пришло время добавить новый узел вУокер ушел.

Та же самая картина применяется кправильноветвь, но теперь входящее значение больше, чемУокерценность. Сначала мы проверим, еслиходок вправоуказывает на другой узел или указывает назначение NULL, Еслиходок вправоуказывает на обновление другого узлаходункиуказать находок вправои начать следующую итерацию.

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

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

функция addNode:

void addNode(int v_) {
if(!root)
root = new node(v_);
else {
node* walker = root;
while(walker) {
if(v_ < walker->val) {
if(walker->left)
walker = walker->left;
else {
walker->left = new node(v_);
walker = NULL;
}
}
else {
if(walker->right)
walker = walker->right;
else {
walker->right = new node(v_);
walker = NULL;
}
}
}
}
}

Отлично, нафункция поиска узлов,

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

Начните с объявления переменной count для подсчета каждой итерации. Далее установите указатель узлаходункиккорень, Пока естьходункиузелискать дерево. Теперь проверьте, совпадают ли значение ходунка и желаемое входное значение. Если это так, номер был найден, вернуть счет. В противном случае пусть троичный оператор определяетУокерследующий ход

Функция findNodeCount:

int findNodeCount(int v_) {
int count = 0;
node* walker = root;
while(walker) {
if(v_ == walker->val)
return count;
walker = (v_ < walker->val) ? walker->left : walker->right;
count++;
}
return -1;
}

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

функция публичной печати:

void print() {
cout<<"Printing binary tree:"<<endl<<"[ ";
print(root);
cout<<"]"<<endl;
}

функция приватной печати:

void print(node* temp) {
if(temp->left)
print(temp->left);
cout<<temp->val<<" ";
if(temp->right)
print(temp->right);
}

Наконец, конструктор для инициализациикореньк нулю.

конструктор класса:

BinaryTree() { root = NULL; }

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

  1. Скопируйтекодв текстовый редактор и сохранить какmain.cpp
  2. Компилировать из командной строки,g++ main.cpp -std=c++11 -o bt.exe
  3. Затем выполните код из командной строки,./bt.exe

После компиляции и выполнения исходного кода программа сгенерирует двоичное дерево 🎉 и выведет количество обходов, необходимых для поиска узла.

Код

Посмотреть код C ++Вот,

Создайте двоичное дерево с помощью веб-приложенияВот,

Оригинальная статья

Footer decor

© www.machinelearningmastery.ru | Ссылки на оригиналы и авторов сохранены. | map