深度使用两个链接列表的邻接列表的首次搜索C 实现

Depth First Search C++ implementation using adjacency list with two linked list

本文关键字:列表 实现 搜索 链接 两个 深度      更新时间:2023-10-16

我是一名大学生,这是我第一次在这里问一个问题。首先,感谢您抽出宝贵的时间阅读。我们有一个关于图形的项目。到目前为止,我通过矩阵和邻接列表创建了图形。我的邻接列表版本由2个链接列表组成(只是允许添加我想要的顶点)。现在,我正在尝试进行深度搜索。我做了一些研究,认真地做我不太了解,所以我遵循自己的思考。边缘..有人可以阅读它,告诉我是否正确?如果是复杂性o(v e)的情况如何?PS:请仅使用C ,因为这是我所知道的唯一语言。非常感谢您的帮助

我在DFS中所做的是

1-do a while循环通过所有顶点并在每个顶点上调用DFS2-在每个顶点,dfs称为,顶点的颜色为灰色('g')3个循环通过目标顶点的子女(边缘)每个孩子4对孩子,另一个孩子将通过搜索 -> value == child-> value
搜索相应的边缘5-当它找到顶点时,它将再次调用DFS(请重复步骤2到5)6-完成,彩色顶点黑色一个接一个

这是代码:

edgenode.h

class EdgeNode
{
public:
    int value;
    EdgeNode *Next;
};

vertexnode.h

#include "EdgeNode.h"
class VertexNode
{
public:
    int value;
    int parentIndex;
    char color;
    EdgeNode *Child;
    VertexNode *Next;
};

Graph.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);

};

graph.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 << ")";
}

我不知道您的项目应该如何组织,但是用邻接列表构建的图的代码可能需要大约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);
}