1. 程式人生 > >資料結構複習——圖的深度優先搜尋

資料結構複習——圖的深度優先搜尋

1、和樹的遍歷類似,我們希望從圖中某一定點出發訪遍圖中的其餘節點,且每個節點僅被訪問一次。

2、實現。

//假定圖最多有20個定點
#define MAX_VERTEX_NUM 20
bool visited[MAX_VERTEX_NUM]={false};
//採用鄰接連結串列的方式來儲存圖中的節點
struct Node
{
    unsigned NodeID_;
    Node* next_;
    Node(unsigned nodeId):
        NodeID_(nodeId),
        next_(nullptr)
    {
    }

    Node()
    {

    }
};

struct Graph
{
    //頭定點組成的陣列
    Node nodeList[MAX_VERTEX_NUM];
    //定點個數、弧的個數
    int verNum_,arcNum_;

    Graph()
    {
    }
};

//建立採用鄰接表儲存的圖
void createAGraph(Graph& graph)
{
    //假定有5個頂點,6條邊
    graph.verNum_=5;
    graph.arcNum_=7;

    for(int i=0;i<graph.verNum_;++i)
    {
        graph.nodeList[i].NodeID_=i;
        graph.nodeList[i].next_=nullptr;
    }
    Node* p2=nullptr;


    for(unsigned i=0;i<5;++i)
    {
        for(unsigned j=0;j<5;++j)
        {
            if(i*j!=4&&i*j!=8&&i*j!=12&&
                    i!=j)
            {
                p2=new Node(j);


                std::cout<<i<<"\t"<<j<<"\t";



                p2->next_=graph.nodeList[i].next_;
                graph.nodeList[i].next_=p2;

            }
        }
        std::cout<<std::endl;
    }
}

void printGraph(Graph& graph)
{
    std::cout<<"輸出頂點資訊:\n";
    Node* curNode=nullptr;

    for(int i=0;i<graph.verNum_;++i)
    {
        std::cout<<"頂點編號"<<graph.nodeList[i].NodeID_<<std::endl;
        curNode=graph.nodeList[i].next_;

        while(curNode)
        {
            std::cout<<":--->"<<curNode->NodeID_;
            curNode=curNode->next_;
        }
        std::cout<<std::endl;
    }
}

/**
 * @brief firstAdjvex 在圖graph中返回頂點編號為adjvexNo對應的鄰接表中的首個節點編號
 * @param graph
 * @param adjvexNo
 * @return
 */
int firstAdjvex(Graph& graph,int adjvexNo)
{
    int  firstNodeID=graph.nodeList[adjvexNo].next_->NodeID_;
    return firstNodeID;
}

/**
 * @brief nextAdjvex 在圖graph的編號nodeListNo對應的鄰接連結串列中返回
 * 編號為adjvexNo的結點的下一個結點編號
 * @param graph
 * @param nodeListNo
 * @param adjvexNo
 * @return
 */
int nextAdjvex(Graph& graph,unsigned nodeListNo,unsigned adjvexNo)
{
    Node* curNode=graph.nodeList[nodeListNo].next_;

    while(curNode)
    {
        if(curNode->NodeID_==adjvexNo&&curNode->next_!=nullptr)
        {
            return curNode->next_->NodeID_;
        }
        curNode=curNode->next_;
    }
    return -1;
}

//從圖graph中以頂點adjvexNo楷書
void DFS(Graph graph,int adjvexNo)
{
    visited[adjvexNo]=true;
    std::cout<<adjvexNo<<"--->\t";
    for(int nextAdjvexNo=firstAdjvex(graph,adjvexNo);nextAdjvexNo>=0;
        nextAdjvexNo=nextAdjvex(graph,adjvexNo,nextAdjvexNo))
    {
        if(visited[nextAdjvexNo]==false)
            DFS(graph,nextAdjvexNo);
    }
}

void DFSTraverse(Graph& graph)
{
    int i=-1;
    for(i=0;i<graph.verNum_;++i)
        visited[i]=false;

    for(i=0;i<graph.verNum_;++i)
    {
        if(visited[i]==false)
            DFS(graph,i);
    }
}




//測試函式
int main()
{
    Graph graph;
    createAGraph(graph);
    printGraph(graph);
    DFSTraverse(graph);
    return 0;
}

3、執行截圖。