mirror of
https://github.com/krahets/hello-algo.git
synced 2026-07-17 11:32:10 +08:00
deploy
This commit is contained in:
@@ -4359,25 +4359,25 @@
|
||||
<h1 id="76">7.6 Краткие итоги<a class="headerlink" href="#76" title="Permanent link">¶</a></h1>
|
||||
<h3 id="1">1. Основные моменты<a class="headerlink" href="#1" title="Permanent link">¶</a></h3>
|
||||
<ul>
|
||||
<li>Двоичное дерево - это нелинейная структура данных, отражающая логику "разделяй и властвуй". Каждый узел двоичного дерева содержит значение и два указателя, которые соответственно ведут к левому и правому дочерним узлам.</li>
|
||||
<li>Двоичное дерево - это нелинейная структура данных, отражающая логику «разделяй и властвуй». Каждый узел двоичного дерева содержит значение и два указателя, которые соответственно ведут к левому и правому дочерним узлам.</li>
|
||||
<li>Для любого узла двоичного дерева дерево, образованное его левым (правым) дочерним узлом и всеми нижележащими узлами, называется левым (правым) поддеревом этого узла.</li>
|
||||
<li>К связанным с двоичным деревом терминам относятся корневой узел, листовой узел, уровень, степень, ребро, высота, глубина и так далее.</li>
|
||||
<li>Инициализация двоичного дерева, вставка узлов и удаление узлов аналогичны операциям со связным списком.</li>
|
||||
<li>К распространенным видам двоичного дерева относятся идеальное двоичное дерево, полное двоичное дерево, строгое двоичное дерево и сбалансированное двоичное дерево. Идеальное двоичное дерево - наиболее желательное состояние, а связный список - худший случай после вырождения.</li>
|
||||
<li>Двоичное дерево можно представить массивом: значения узлов и пустые позиции располагаются в порядке обхода по уровням, а связи между родителем и детьми реализуются через индексацию.</li>
|
||||
<li>Обход двоичного дерева по уровням является методом поиска в ширину; он отражает идею "расширяться от центра к периферии слой за слоем" и обычно реализуется через очередь.</li>
|
||||
<li>Прямой, симметричный и обратный обходы относятся к поиску в глубину; они отражают идею "сначала дойти до конца, затем вернуться и продолжить" и обычно реализуются рекурсивно.</li>
|
||||
<li>Двоичное дерево поиска - это эффективная структура данных для поиска элементов; его поиск, вставка и удаление имеют временную сложность <span class="arithmatex">\(O(\log n)\)</span> . Когда двоичное дерево поиска вырождается в связный список, все эти сложности деградируют до <span class="arithmatex">\(O(n)\)</span> .</li>
|
||||
<li>Обход двоичного дерева по уровням является методом поиска в ширину. Он отражает идею «расширяться от центра к периферии слой за слоем» и обычно реализуется через очередь.</li>
|
||||
<li>Прямой, симметричный и обратный обходы относятся к поиску в глубину. Они отражают идею «сначала дойти до конца, затем вернуться и продолжить» и обычно реализуются рекурсивно.</li>
|
||||
<li>Двоичное дерево поиска - это эффективная структура данных для поиска элементов. Его поиск, вставка и удаление имеют временную сложность <span class="arithmatex">\(O(\log n)\)</span> . Когда двоичное дерево поиска вырождается в связный список, все эти сложности деградируют до <span class="arithmatex">\(O(n)\)</span> .</li>
|
||||
<li>AVL-дерево, также называемое сбалансированным двоичным деревом поиска, с помощью вращений гарантирует, что после постоянных вставок и удалений узлов дерево остается сбалансированным.</li>
|
||||
<li>Вращения AVL-дерева включают правое вращение, левое вращение, сначала правое затем левое и сначала левое затем правое. После вставки или удаления узла AVL-дерево выполняет вращения снизу вверх, чтобы снова восстановить баланс.</li>
|
||||
</ul>
|
||||
<h3 id="2-q-a">2. Q & A<a class="headerlink" href="#2-q-a" title="Permanent link">¶</a></h3>
|
||||
<p><strong>Q</strong>: Для двоичного дерева, состоящего из одного узла, высота дерева и глубина корня обе равны <span class="arithmatex">\(0\)</span> ?</p>
|
||||
<p>Да, потому что высота и глубина обычно определяются как "число пройденных ребер".</p>
|
||||
<p><strong>Q</strong>: Вставка и удаление в двоичном дереве обычно выполняются в составе набора операций. Что именно означает этот "набор операций"? Можно ли понимать это как освобождение ресурсов у дочерних узлов ресурса?</p>
|
||||
<p>Да, потому что высота и глубина обычно определяются как «число пройденных ребер».</p>
|
||||
<p><strong>Q</strong>: Вставка и удаление в двоичном дереве обычно выполняются в составе набора операций. Что именно означает этот «набор операций»? Можно ли понимать это как освобождение ресурсов у дочерних узлов ресурса?</p>
|
||||
<p>Возьмем в качестве примера двоичное дерево поиска: операция удаления узла делится на три случая, и каждый из этих случаев требует нескольких последовательных шагов работы с узлами.</p>
|
||||
<p><strong>Q</strong>: Почему у DFS для двоичного дерева есть три порядка: прямой, симметричный и обратный? Для чего они нужны?</p>
|
||||
<p>Подобно прямому и обратному обходу массива, прямой, симметричный и обратный обходы - это три способа обхода двоичного дерева, с помощью которых можно получить результаты в определенном порядке. Например, в двоичном дереве поиска, где соблюдается отношение <code>значение левого дочернего узла < значение корня < значение правого дочернего узла</code> , если обходить дерево с приоритетом "лево <span class="arithmatex">\(\rightarrow\)</span> корень <span class="arithmatex">\(\rightarrow\)</span> право", то получится упорядоченная последовательность узлов.</p>
|
||||
<p>Подобно прямому и обратному обходу массива, прямой, симметричный и обратный обходы - это три способа обхода двоичного дерева, с помощью которых можно получить результаты в определенном порядке. Например, в двоичном дереве поиска, где соблюдается отношение <code>значение левого дочернего узла < значение корня < значение правого дочернего узла</code> , если обходить дерево с приоритетом «лево <span class="arithmatex">\(\rightarrow\)</span> корень <span class="arithmatex">\(\rightarrow\)</span> право», то получится упорядоченная последовательность узлов.</p>
|
||||
<p><strong>Q</strong>: Правое вращение работает с отношениями между <code>node</code> , <code>child</code> и <code>grand_child</code> . А связь между <code>node</code> и его исходным родителем разве не нужно поддерживать? После правого вращения она ведь не оборвется?</p>
|
||||
<p>На это нужно смотреть с точки зрения рекурсии. В правое вращение <code>right_rotate(root)</code> передается корень поддерева, а затем через <code>return child</code> возвращается корень этого поддерева уже после вращения. Соединение между новым корнем поддерева и его родителем восстанавливается после возврата функции и не входит в обязанности самой операции правого вращения.</p>
|
||||
<p><strong>Q</strong>: В C++ функции делятся на <code>private</code> и <code>public</code> . Какая логика стоит за этим? Почему <code>height()</code> и <code>updateHeight()</code> помещают в разные области видимости?</p>
|
||||
|
||||
Reference in New Issue
Block a user