Під час обходу дерева / графіка яка різниця між першою шириною та глибиною? Будь-які приклади кодування або псевдокоду були б чудовими.
Під час обходу дерева / графіка яка різниця між першою шириною та глибиною? Будь-які приклади кодування або псевдокоду були б чудовими.
Відповіді:
Ці два терміни розрізняють два різні способи ходіння по дереву.
Напевно, найпростіше просто проявити різницю. Розглянемо дерево:
A
/ \
B C
/ / \
D E F
Глибини першого обходу буде відвідувати вузли в такому порядку
A, B, D, C, E, F
Зауважте, що ви рухаєтесь повністю вниз однією ногою, перш ніж рухатися далі.
Ширину першого обходу буде відвідати вузол в цьому порядку
A, B, C, D, E, F
Тут ми працюємо весь рівень на кожному рівні перед тим, як спуститися.
(Зверніть увагу, що в порядках обходу є деяка неоднозначність, і я обманував підтримувати порядок "читання" на кожному рівні дерева. У будь-якому випадку я міг дістатися до B до або після C, і так само я міг би дістатися до Е до або після F. Це може бути, а може не мати значення, залежить від вашої програми ...)
Обидва види обходу можна досягти за допомогою псевдокоду:
Store the root node in Container
While (there are nodes in Container)
N = Get the "next" node from Container
Store all the children of N in Container
Do some work on N
Різниця між двома обхідними порядками полягає у виборі Container
.
Як виглядає рекурсивна реалізація
ProcessNode(Node)
Work on the payload Node
Foreach child of Node
ProcessNode(child)
/* Alternate time to work on the payload Node (see below) */
Рекурсія закінчується, коли ви досягнете вузла, у якого немає дітей, тому він гарантовано закінчиться для кінцевих, ациклічних графіків.
У цей момент я ще трохи обдурив. З невеликою кмітливістю ви також можете працювати над вузлами в такому порядку:
D, B, E, F, C, A
що є варіантом глибини спочатку, де я не виконую роботу на кожному вузлі, поки я не йду назад по дереву. Однак я відвідав вищі вузли, щоб знайти своїх дітей.
Ця траверсія є досить природною для рекурсивної реалізації (використовуйте вищезазначений рядок "Черговий час" замість першого рядка "Робота"), і не надто складно, якщо ви використовуєте явний стек, але я залишу це як вправу.
A, B, D, C, E, F
- перший представлений), інфікс ( D, B, A, E, C, F
- використовується для сортування: додайте як дерево AVL, потім прочитайте інфікс) або постфікс ( D, B, E, F, C, A
альтернативно представлений) обхід. Імена задаються позицією, в якій ви обробляєте корінь. Слід зазначити, що інфіксація справді має сенс для двійкових дерев. @batbrat це імена ... враховуючи час, коли ви запитали, ви, мабуть, уже знаєте.
Ця картина повинна дати вам уявлення про контекст, у якому вживаються слова ширина та глибина .
Алгоритм пошуку на глибині першого дії працює так, ніби він хоче якомога швидше відійти від початкової точки.
Зазвичай він використовує, Stack
щоб пам’ятати, куди він повинен піти, коли він досяг тупику.
Правила, які слід виконувати: Першу вершину А натисніть на Stack
Код Java:
public void searchDepthFirst() {
// Begin at vertex 0 (A)
vertexList[0].wasVisited = true;
displayVertex(0);
stack.push(0);
while (!stack.isEmpty()) {
int adjacentVertex = getAdjacentUnvisitedVertex(stack.peek());
// If no such vertex
if (adjacentVertex == -1) {
stack.pop();
} else {
vertexList[adjacentVertex].wasVisited = true;
// Do something
stack.push(adjacentVertex);
}
}
// Stack is empty, so we're done, reset flags
for (int j = 0; j < nVerts; j++)
vertexList[j].wasVisited = false;
}
Застосування : Швидкісні пошуки часто використовуються для моделювання ігор (та ігрових ситуацій у реальному світі). У типовій грі ви можете вибрати одну з кількох можливих дій. Кожен вибір призводить до подальших виборів, кожен з яких призводить до подальших виборів тощо, до графіку можливостей дерева, що постійно розширюється.
Queue
.Код Java:
public void searchBreadthFirst() {
vertexList[0].wasVisited = true;
displayVertex(0);
queue.insert(0);
int v2;
while (!queue.isEmpty()) {
int v1 = queue.remove();
// Until it has no unvisited neighbors, get one
while ((v2 = getAdjUnvisitedVertex(v1)) != -1) {
vertexList[v2].wasVisited = true;
// Do something
queue.insert(v2);
}
}
// Queue is empty, so we're done, reset flags
for (int j = 0; j < nVerts; j++)
vertexList[j].wasVisited = false;
}
Застосування : Перший за шириною пошук спочатку знаходить усі вершини, які знаходяться в одному краю від початкової точки, потім всі вершини, які знаходяться в двох краях, і так далі. Це корисно, якщо ви намагаєтесь знайти найкоротший шлях від початкової вершини до заданої вершини.
Сподіваємось, цього має бути достатньо для розуміння пошуків Хліб-Перший та Глибина-Перший. Для подальшого читання я рекомендую розділ "Графіки" із чудової книги структур Роберта Лафора.
Враховуючи це двійкове дерево:
Перший обхід ширини:
переходьте через кожен рівень зліва направо.
"Я G, мої діти D і я, мої бабусі - B, E, H і K, їхні бабусі - A, C, F"
- Level 1: G
- Level 2: D, I
- Level 3: B, E, H, K
- Level 4: A, C, F
Order Searched: G, D, I, B, E, H, K, A, C, F
Перший обхід по глибині:
обхід не робиться ЗА ВСІХ цілих рівнів одночасно. Натомість, обхід занурюється спочатку в ГЛИБУ (від кореня до листа) дерева. Однак це трохи складніше, ніж просто вгору і вниз.
Існує три методи:
1) PREORDER: ROOT, LEFT, RIGHT.
You need to think of this as a recursive process:
Grab the Root. (G)
Then Check the Left. (It's a tree)
Grab the Root of the Left. (D)
Then Check the Left of D. (It's a tree)
Grab the Root of the Left (B)
Then Check the Left of B. (A)
Check the Right of B. (C, and it's a leaf node. Finish B tree. Continue D tree)
Check the Right of D. (It's a tree)
Grab the Root. (E)
Check the Left of E. (Nothing)
Check the Right of E. (F, Finish D Tree. Move back to G Tree)
Check the Right of G. (It's a tree)
Grab the Root of I Tree. (I)
Check the Left. (H, it's a leaf.)
Check the Right. (K, it's a leaf. Finish G tree)
DONE: G, D, B, A, C, E, F, I, H, K
2) INORDER: LEFT, ROOT, RIGHT
Where the root is "in" or between the left and right child node.
Check the Left of the G Tree. (It's a D Tree)
Check the Left of the D Tree. (It's a B Tree)
Check the Left of the B Tree. (A)
Check the Root of the B Tree (B)
Check the Right of the B Tree (C, finished B Tree!)
Check the Right of the D Tree (It's a E Tree)
Check the Left of the E Tree. (Nothing)
Check the Right of the E Tree. (F, it's a leaf. Finish E Tree. Finish D Tree)...
Onwards until...
DONE: A, B, C, D, E, F, G, H, I, K
3) POSTORDER:
LEFT, RIGHT, ROOT
DONE: A, C, B, F, E, D, H, K, I, G
Використання (він же, чому нас хвилює):
мені дуже сподобалося це просте пояснення Quora методів обходу глибин першої глибини та того, як вони звичайно використовуються:
"Перетинання замовлення надрукує значення [для BST (двійкове дерево пошуку)] "
" Обхід попереднього замовлення використовується для створення копії [двійкового дерева пошуку]. "
Msgstr "Перехід після замовлення використовується для видалення [двійкового дерева пошуку]."
https://www.quora.com/What-is-the-use-of-pre-order-and-post-order-traversal-of-binary-trees-in-computing
Думаю, було б цікаво написати їх обом таким чином, що лише перемикаючи рядки коду, ви дасте вам один алгоритм чи інший, щоб ви побачили, що ваша дилема не така сильна, як здається спочатку .
Мені особисто подобається трактування BFS як затоплення ландшафту: спочатку затоплені ділянки з низькою висотою, і лише після цього слідкують за висотними районами. Якщо ви уявляєте висоту ландшафту такою ж ізолінією, як ми бачимо в географічних книгах, легко зрозуміти, що BFS заповнює всю площу під одним і тим же ізоліном одночасно, як це було б з фізикою. Таким чином, інтерпретація висот як відстані чи масштабується вартість дає досить інтуїтивне уявлення про алгоритм.
Маючи це на увазі, ви можете легко адаптувати ідею за шириною першого пошуку, щоб легко знайти мінімальне прольотове дерево, найкоротший шлях, а також безліч інших алгоритмів мінімізації.
Я ще не бачив будь-якої інтуїтивно зрозумілої інтерпретації DFS (лише стандартну про лабіринт, але вона не така потужна, як BFS та затоплення), тому для мене здається, що BFS здається краще співвідноситься з фізичними явищами, як описано вище, тоді як DFS краще співвідноситься з варіантами дилеми на раціональних системах (тобто люди чи комп’ютери, які вирішують, який рух рухати в шахову гру чи виходити з лабіринту).
Отже, для мене різниця між брехнею, щодо того, яке природне явище найкраще відповідає їхній моделі поширення (поперек) у реальному житті.