使用具有两个链表的邻接表的深度优先搜索 C++ 实现

Posted

技术标签:

【中文标题】使用具有两个链表的邻接表的深度优先搜索 C++ 实现【英文标题】:Depth First Search C++ implementation using adjacency list with two linked list 【发布时间】:2016-12-09 20:21:09 【问题描述】:

我是一名大学生,这是我第一次在这里提问。首先感谢您花时间阅读。我们有一个关于图表的项目。到目前为止,我通过 matrix 和 adjacency list 创建了图形。我的邻接表版本由 2 个链表组成(只是为了允许添加我想要的尽可能多的顶点)。 现在我正在尝试进行深度优先搜索。我做了一些研究,严重的是我不太了解,所以我遵循了自己的想法。它正在工作,但我不确定它是否正确或者复杂度是否为 O(V+E) v 是指顶点,E 是边缘..任何人都可以阅读并告诉我它是否正确?如果是 O(V+E) 的复杂度如何? PS:请只使用 c++,因为它是我知道的唯一语言。 非常感谢您的帮助

我在 DFS 中所做的是

1-做一个遍历所有顶点并在每个顶点上调用DFS的while循环 2-在每个顶点上,调用DFS,顶点的颜色将是灰色('g') 3-另一个遍历目标顶点的子节点(边缘)的while循环 4-在每个 children 上,另一个 while 循环将通过 search-> value == child->value 搜索相应的边 5-当它找到顶点时,它会再次调用 DFS(所以重复第 2 步到第 5 步) 6-完成后,依次将顶点着色为黑色

代码如下:

EdgeNode.h

class EdgeNode

public:
    int value;
    EdgeNode *Next;
;

顶点节点.h

#include "EdgeNode.h"
class VertexNode

public:
    int value;
    int parentIndex;
    char color;
    EdgeNode *Child;
    VertexNode *Next;
;

图形.h

#include "VertexNode.h"

class Graph
public:

    int NbVertex;
    int time;
    VertexNode *s;
    Graph();
    void AddVertex(int value);
    bool AddEdge(int parentIndex, int value);
    void PrintVertex();
    void PrintGraph();
    void DepthFirstSearch();
    void DFS(VertexNode *V);


;

图形.cpp

#include <iostream>
#include "Graph.h"
#include <string>
using namespace std;


Graph::Graph()

    s = NULL;
    NbVertex = 0;


void Graph::AddVertex(int value)

    if (NbVertex == 0)
    
        s = new VertexNode;
        s->value = value;
        s->parentIndex = NbVertex+1;
        s->color = 'w';
        s->Child = NULL;
        s->Next = NULL;
    

    else
    
        VertexNode *z = s;
        while (z->Next != NULL)
        
            z = z->Next;
        
        z->Next = new VertexNode;
        z->Next->parentIndex = NbVertex+1;
        z->Next->color = 'w';
        z->Next->value = value;
        z->Next->Child = NULL;
        z->Next->Next = NULL;
    


    NbVertex++;



bool Graph::AddEdge(int parentIndex, int value)

    if (NbVertex == 0)
        cout << "Graph is empty" << endl;

    VertexNode *z = s;

        while (z != NULL)
        
            if (z->parentIndex == parentIndex)
            


                if (z->Child == NULL)
                
                    EdgeNode *y = new EdgeNode;
                    y->value = value;
                    y->Next = NULL;
                    z->Child = y;

                

                else
                
                    EdgeNode *y = z->Child;
                    while (y->Next != NULL)
                    
                        if (y->value == value)
                        
                            cout << "The edge already exists"<<endl;
                            return false;
                        

                        y = y->Next;
                    
                    y->Next = new EdgeNode;
                    y->Next->value = value;
                    y->Next->Next = NULL;

                

                return true;

            

            z = z->Next;

        

        cout << "The index was not found" << endl;
    return false;




void Graph :: PrintVertex()

    VertexNode *z = s;
    int count = 1;
    while (z != NULL)
    
        cout << "vertex " << count << " : " << endl;
        cout << "Value : " << z->value << endl;
        cout << "Index : " << z->parentIndex << endl;
        cout << "Next : " << z->Next << endl;
        cout << "Child : " << z->Child << endl;
        cout << "Color : "  << z->color << endl;
        cout << endl;
        count++;
        z = z->Next;
    

    cout << "time is : " << time;



void Graph::PrintGraph()

    VertexNode *z = s;
    int countVertex = 1;
    while (z != NULL)
    
        cout << "vertex " << countVertex << " : " << endl;
        cout << "Value : " << z->value << endl;
        cout << "Index : " << z->parentIndex << endl;
        cout << "Next : " << z->Next << endl;
        cout << "Child : " << z->Child << endl;
        cout << endl;
        countVertex++;
        if (z->Child != NULL)
        
            int countChild=1;
            EdgeNode *y = z->Child;
            while (y != NULL)
            
                cout << "Child " << countChild << " : " << endl;
                cout << "Value : " << y->value << endl;
                cout <<"Next : " << y->Next << endl;
                cout << "-------------------"<<endl;
                countChild++;
                y = y->Next;
            

        

        cout << "*************************************"<<endl;

        z = z->Next;
    




void Graph :: DepthFirstSearch()

    time = 0;
    VertexNode *z = s;
    while (z != NULL)
    
        if (z->color == 'w')
        
            DFS(z);
        
        z = z->Next;
    


void Graph::DFS(VertexNode *V)

    cout << "(" << V->value;
    V->color = 'g';
    time++;

    EdgeNode *Y = V->Child;
    while (Y != NULL)
    
        VertexNode *Search = s;
        while (Search != NULL)
        
            if (Search->value == Y->value)
            
                if (Search->color == 'w')
                
                    DFS(Search);
                
                /*else
                
                    Search->color = 'b';
                */
            

            Search = Search->Next;

        

        Y = Y->Next;
    

    V->color = 'b';
    time++;
    cout << V->value << ")";

这是 DFS

void Graph :: DepthFirstSearch()

    time = 0;
    VertexNode *z = s;
    while (z != NULL)
    
        if (z->color == 'w')
        
            DFS(z);
        
        z = z->Next;
    


void Graph::DFS(VertexNode *V)

    cout << "(" << V->value;
    V->color = 'g';
    time++;

    EdgeNode *Y = V->Child;
    while (Y != NULL)
    
        VertexNode *Search = s;
        while (Search != NULL)
        
            if (Search->value == Y->value)
            
                if (Search->color == 'w')
                
                    DFS(Search);
                
                /*else
                
                    Search->color = 'b';
                */
            

            Search = Search->Next;

        

        Y = Y->Next;
    

    V->color = 'b';
    time++;
    cout << V->value << ")";

【问题讨论】:

【参考方案1】:

我不知道你的项目应该如何组织,但是使用邻接表构建的图形的代码可能需要大约 10 行。

快速查看,您的 DFS 似乎是正确的。理论上,DFS(或 BFS)时间是 O(V + E),因为它会经过所有顶点和所有边(总计 O(|V| + |E|)。

如果您关心代码阅读和组织,请继续前进,但如果您更喜欢更少的代码,我相信您可以找到更小的图表实现。

有一个 5 行的 DFS 实现可以正常工作。

void DFS(graph G, int v)
    mark[v] = true;
    cout<<"Visiting "<<v<<endl;
    for(auto u : G[v]) //this means "for all u in the adjacence list of v"
        if(!mark[u]) DFS(G, u);

【讨论】:

以上是关于使用具有两个链表的邻接表的深度优先搜索 C++ 实现的主要内容,如果未能解决你的问题,请参考以下文章

c语言图的遍历,邻接表存储,深度,广度优先遍历

深度优先搜索

编程实现以邻接表或邻接矩阵为存储结构,图的广度和深度优先搜索

深度优先算法和广度优先算法

第六章总结--图

图的深度/广度优先遍历C语言程序