簡體   English   中英

深度優先搜索:格式化輸出?

[英]Depth First Search: Formatting output?

如果我有以下圖表:

  Marisa  Mariah
       \  / 
Mary---Maria---Marian---Maryanne
         |
Marley--Marla

如果“瑪麗”是我的起點,我應該如何實現深度優先搜索功能?

Mary
   Maria
       Marisa
       Mariah
       Marian
            Maryanne
       Marla
            Merley

我確實知道空格的數量等於頂點(名稱)的深度,但我不知道如何編碼。 以下是我的功能:

void DFS(Graph g, Vertex origin)
{
    stack<Vertex> vertexStack;
    vertexStack.push(origin);
    Vertex currentVertex;
    int currentDepth = 0;

    while( ! vertexStack.empty() )
    {
        currentVertex = vertexStack.top();
        vertexStack.pop();

        if(currentVertex.visited == false)
        {
            cout << currentVertex.name << endl;

            currentVertex.visited = true;
            for(int i = 0; i < currentVertex.adjacencyList.size(); i++)
                vertexStack.push(currentVertex.adjacencyList[i]);
        }

    }
}

謝謝你的幫助 !

只需將節點及其深度存儲在堆棧中:

std::stack<std::pair<Vertex, int>> vertexStack;
vertexStack.push(std::make_pair(origin, 0));
// ...
std::pair<Vertex, int> current = vertexStack.top();
Vertex currentVertex = current.first;
int     depth        = current.second;

如果你想獲得花哨,你可以使用std::tie()來增加兩個值:

Vertex currentVertex;
int    depth;
std::tie(currentVertex, depth) = vertexStack.top();

知道depth您只需適當地縮進輸出。

你的堆棧的當前大小是BTW,不必要地深! 我認為對於完整的圖,它可能包含O(N * N)個元素(更確切地說,(N-1)*(N-2))。 問題是你推送了許多可能被訪問過的節點。

假設使用隱式堆棧(即遞歸)是不可能的(它不適用於大型圖形,因為您可能會出現堆棧溢出),實現深度優先搜索的正確方法是:

  1. 推送堆棧上的當前節點和邊緣
  2. 標記訪問的頂級節點並使用堆棧深度作為縮進打印它
  3. 如果沒有節點
  4. 如果頂部節點包含一個未訪問的節點(增加邊緣迭代器直到找到這樣的節點),請轉到1。
  5. 否則(邊緣迭代器到達終點)刪除頂部節點並轉到3。

在代碼中,這看起來像這樣:

std::stack<std::pair<Node, int> > stack;

stack.push(std::make_pair(origin, 0));
while (!stack.empty()) {
    std::pair<Node, int>& top = stack.top();
    for (; top.second < top.first.adjacencyList.size(); ++top.second) {
         Node& adjacent = top.first.adjacencyList[top.second];
         if (!adjacent.visited) {
              adjacent.visted = true;
              stack.push(std::make_pair(adjacent, 0));
              print(adjacent, stack.size());
              break;
         }
     }
     if (stack.top().first.adjacencyList.size() == stack.top().second) {
          stack.pop();
     }
 }

Rep(Tree)成為樹Tree的表示。 然后, Rep(Tree)看起來像這樣:

Root
  <Rep(Subtree rooted at node 1)>
  <Rep(Subtree rooted at node 2)>
               .
               .
               .

因此,讓您的dfs函數只返回以該節點為根的子樹的表示,並相應地修改該值。 或者,只需告訴每個dfs調用打印以該節點為根的樹的表示,但將其傳遞給當前深度。 這是后一種方法的示例實現。

void PrintRep(const Graph& g, Vertex current, int depth)
{
   cout << std::string(' ', 2*depth) << current.name << endl;
   current.visited = true;
   for(int i = 0; i < current.adjacencyList.size(); i++)
      if(current.adjacencyList[i].visited == false)
         PrintRep(g, current.adjacencyList[i], depth+1);           
}

您可以使用您的原點和深度0調用此函數,如下所示:

PrintRep(g, origin, 0);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM