Ширина першої проти глибини першої


172

Під час обходу дерева / графіка яка різниця між першою шириною та глибиною? Будь-які приклади кодування або псевдокоду були б чудовими.


6
Перевірили чи ви википедию ( глибину першої , широту перший )? На цих сторінках є приклади коду, а також безліч гарних зображень.
rmeador

У мене теж була така думка, але тоді наведені приклади трохи приємніші, ніж ті, що знайдені у Вікіпедії ....
jonnybazookatone

Відповіді:


292

Ці два терміни розрізняють два різні способи ходіння по дереву.

Напевно, найпростіше просто проявити різницю. Розглянемо дерево:

    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

що є варіантом глибини спочатку, де я не виконую роботу на кожному вузлі, поки я не йду назад по дереву. Однак я відвідав вищі вузли, щоб знайти своїх дітей.

Ця траверсія є досить природною для рекурсивної реалізації (використовуйте вищезазначений рядок "Черговий час" замість першого рядка "Робота"), і не надто складно, якщо ви використовуєте явний стек, але я залишу це як вправу.


@dmckee Дякую! Я вважаю, ви мали на увазі "Робота над корисним навантаженням у Node", правда?
батбрат

4
Можливо, варто відзначити, що ви можете змінити першу глибинну версію, щоб отримати префікс ( A, B, D, C, E, F- перший представлений), інфікс ( D, B, A, E, C, F- використовується для сортування: додайте як дерево AVL, потім прочитайте інфікс) або постфікс ( D, B, E, F, C, Aальтернативно представлений) обхід. Імена задаються позицією, в якій ви обробляєте корінь. Слід зазначити, що інфіксація справді має сенс для двійкових дерев. @batbrat це імена ... враховуючи час, коли ви запитали, ви, мабуть, уже знаєте.
Тераот

@Theraot дякую за додавання цього в! Так, я знаю про подібні траверси і чому Infix має сенс лише для двійкових дерев.
батбрат

Як вирішити, яке рішення має кращу просторову чи часову складність?
ІгорГанапольський

1
@IgorGanapolsky Повинен бути однаковим для обох в принципі (адже вони використовують по суті один і той же код). Більш цікавим питанням буде те, як вони впливають на кеш і робочий набір, але я думаю, що це буде залежати від морфології дерева.
dmckee --- кошеня колишнього модератора

95

Розуміння умов:

Ця картина повинна дати вам уявлення про контекст, у якому вживаються слова ширина та глибина .

Розуміння ширини та глибини


Поглиблений пошук:

Глибинний перший пошук

  • Алгоритм пошуку на глибині першого дії працює так, ніби він хоче якомога швидше відійти від початкової точки.

  • Зазвичай він використовує, Stackщоб пам’ятати, куди він повинен піти, коли він досяг тупику.

  • Правила, які слід виконувати: Першу вершину А натисніть на Stack

    1. Якщо можливо, відвідайте сусідню небачену вершину, позначте її як відвідувану та натисніть на стек.
    2. Якщо ви не можете виконувати правило 1, то, якщо можливо, висуньте вершину зі стека.
    3. Якщо ви не можете дотримуватися правила 1 або 2, ви закінчите.
  • Код 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.
  • Правила, які слід дотримуватися: Зробіть запуску вершини A поточною вершиною
    1. Відвідайте наступну нерозглянуту вершину (якщо така є), що прилягає до поточної вершини, позначте її та вставте її у чергу.
    2. Якщо ви не можете виконати правило 1, оскільки немає більше небачених вершин, видаліть вершину з черги (якщо це можливо) та зробіть її поточною вершиною.
    3. Якщо ви не можете виконати правило 2, тому що черга порожня, ви закінчите.
  • Код 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;
    }
    
  • Застосування : Перший за шириною пошук спочатку знаходить усі вершини, які знаходяться в одному краю від початкової точки, потім всі вершини, які знаходяться в двох краях, і так далі. Це корисно, якщо ви намагаєтесь знайти найкоротший шлях від початкової вершини до заданої вершини.

Сподіваємось, цього має бути достатньо для розуміння пошуків Хліб-Перший та Глибина-Перший. Для подальшого читання я рекомендую розділ "Графіки" із чудової книги структур Роберта Лафора.


6
Якби я мав ще десять голосів за право, я би це зробив.
snr

@snr ви могли вручити винагороду;)
Сніг

@ Знаю, якщо ти розкажеш його директиви, я можу. Я не знаю, як це зробити.
ЗСШ

Дякую @snr, мені так приємно отримати свою першу нагороду. Я дуже ціную.
Йогеш Умеш Ваїті

1
Дякую @Snow, я радий, що ти знайшов мою відповідь корисною.
Йогеш Умеш Ваїті

4

Враховуючи це двійкове дерево:

введіть тут опис зображення

Перший обхід ширини:
переходьте через кожен рівень зліва направо.

"Я 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


2

Думаю, було б цікаво написати їх обом таким чином, що лише перемикаючи рядки коду, ви дасте вам один алгоритм чи інший, щоб ви побачили, що ваша дилема не така сильна, як здається спочатку .

Мені особисто подобається трактування BFS як затоплення ландшафту: спочатку затоплені ділянки з низькою висотою, і лише після цього слідкують за висотними районами. Якщо ви уявляєте висоту ландшафту такою ж ізолінією, як ми бачимо в географічних книгах, легко зрозуміти, що BFS заповнює всю площу під одним і тим же ізоліном одночасно, як це було б з фізикою. Таким чином, інтерпретація висот як відстані чи масштабується вартість дає досить інтуїтивне уявлення про алгоритм.

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

Я ще не бачив будь-якої інтуїтивно зрозумілої інтерпретації DFS (лише стандартну про лабіринт, але вона не така потужна, як BFS та затоплення), тому для мене здається, що BFS здається краще співвідноситься з фізичними явищами, як описано вище, тоді як DFS краще співвідноситься з варіантами дилеми на раціональних системах (тобто люди чи комп’ютери, які вирішують, який рух рухати в шахову гру чи виходити з лабіринту).

Отже, для мене різниця між брехнею, щодо того, яке природне явище найкраще відповідає їхній моделі поширення (поперек) у реальному житті.


1
Ви можете реалізувати їх за аналогічним алгоритмом, просто використовуйте стек для DFS та чергу для BFS. Проблема BFS полягає в тому, що вам потрібно відслідковувати всі бачені до цього часу вузли. DFS з фізики .. Я уявляю альтернативні всесвіти, і ти хочеш одне з життям, всі діти корінців, різні великі чуби, і ти йдеш увесь шлях до смерті Всесвіту, немає життя? ви повертаєтесь до останньої біфуркації і намагаєтесь черговий поворот, поки всі не вичерпаються, і ви переходите до наступного великого удару, встановлюючи нові фізичні закони для нового Всесвіту. супер інтуїтивно зрозумілий. хороша проблема - пошук шляху з конем у шаховій дошці.
juanmf
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.