图的广度优先搜索与深度优先搜索

一、图的广度优先搜索(邻接链表)

//Link_Graph.h
#include <iostream>
#include <queue>
using namespace std;

#define N 100
#define WHITE 0
#define GRAY 1
#define BLACK 2

queue<int> Q;
struct Vertex;
struct Edge
{
    int start;
    int end;
    int value;
    Edge *next;
    Edge(int s, int e, int v) :start(s), end(e), value(v), next(nullptr){}
};

struct Vertex
{
    int color;
    int d;
    int Pie;
    Edge *head;
    Vertex() :head(nullptr), color(WHITE), d(0x7fffffff), Pie(0) {};
};

class Link_Graph
{
public:
    int n;
    Vertex *V;
    Link_Graph(int num) :n(num)
    {
        V = new Vertex[n + 1];
    }
    ~Link_Graph(){ delete[]V; }
    void AddSingleEdge(int start, int end, int value = 1)
    {
        Edge *NewEdge = new Edge(start, end, value);
        if (V[start].head == NULL || V[start].head->end > end)
        {
            NewEdge->next = V[start].head;
            V[start].head = NewEdge;
        }
        else
        {
            Edge *e = V[start].head, *pre = e;
            while (e != NULL&&e->end < end)
            {
                pre = e;
                e = e->next;
            }
            if (e&&e->end == end)
            {
                delete NewEdge;
                return;
            }
            NewEdge->next = e;
            pre->next = NewEdge;
        }
    }

    void AddDoubleEdge(int a, int b, int value = 1)
    {
        AddSingleEdge(a, b, value);
        AddSingleEdge(b, a, value);
    }

    void DeleteSingleEdge(int start, int end)
    {
        Edge *e = V[start].head, *pre = e;
        while (e&&e->end < end)
        {
            pre = e;
            e = e->next;
        }
        if (e == NULL || e->end>end)
            return;
        if (e == V[start].head)
            V[start].head = e->next;
        else
            pre->next = e->next;
        delete e;
    }
    void DeleteDoubleEdge(int a, int b)
    {
        DeleteSingleEdge(a, b);
        DeleteSingleEdge(b, a);
    }

    void BFS(int s);
    void Print_Path(int s, int v);
};

void Link_Graph::BFS(int s)
{
    int i;
    for (i = 1; i <= n; i++)
    {
        V[i].color = WHITE;
        V[i].d = 0x7fffffff;
        V[i].Pie = 0;
    }
    V[s].color = GRAY;
    V[s].d = 0;
    V[s].Pie = 0;
    while (!Q.empty())
        Q.pop();
    Q.push(s);
    while (!Q.empty())
    {
        int u, v;
        u = Q.front();
        Q.pop();
        Edge *e = V[u].head;
        while (e)
        {
            v = e->end;
            if (V[v].color == WHITE)
            {
                V[v].color = GRAY;
                V[v].d = V[u].d + 1;
                V[v].Pie = u;
                Q.push(v);
            }
            e = e->next;
        }
        V[u].color = BLACK;
    }
}

void Link_Graph::Print_Path(int s, int v)
{
    BFS(s);
    if (v == s)
        cout << s << " ";
    else
    {
        if (V[v].Pie == 0)
            cout << "no path from" << s << "to" << v << "exists.";
        else
        {
            Print_Path(s, V[v].Pie);
            cout << v << " ";
        }
    }
}


//main.cpp
#include <iostream>  
#include "Link_Graph.h"  
using namespace std;  
/* 
1 2 
1 5 
2 6 
6 7 
6 3 
3 7 
3 4 
7 8 
7 4 
4 8 
*/  
int main()  
{  
    Link_Graph *G = new Link_Graph(8);  
    int i = 0, a, b;  
    for(i = 1; i <= 10; i++)  
    {  
        cin>>a>>b;  
        G->AddDoubleEdge(a,b);  
    }  
    G->BFS(2);  
    for(i = 1; i <= 8; i++)  
        cout<<G->V[i].d<<' ';  
    cout<<endl;  
    int s, v;  
    while(cin>>s>>v)  
    {  
        G->Print_Path(s, v);  
        cout<<endl;  
    }  
    return 0;  
}  

二、图的广度优先搜索(邻接矩阵)

//Mat_Graph.h
#include <iostream>  
#include <queue>  
using namespace std;  

#define N 100  
#define WHITE 0  
#define GRAY 1  
#define BLACK 2  

queue<int> Q;  

class Mat_Graph  
{  
public:  
    int n;  
    int color[N+1];  
    int d[N+1];  
    int Pie[N+1];  
    int Map[N+1][N+1];  

    Mat_Graph(int num):n(num)  
    {  
        memset(Map, 0, sizeof(Map));  
    }  
    void AddDoubleEdge(int a, int b, int value = 1)  
    {  
        AddSingleEdge(a, b, value);  
        AddSingleEdge(b, a, value);  
    }  
    void AddSingleEdge(int start, int end, int value = 1)  
    {  
        Map[start][end] = value;  
    }  
    void DeleteDoubleEdge(int a, int b)  
    {  
        DeleteSingleEdge(a, b);  
        DeleteSingleEdge(b, a);  
    }  
    void DeleteSingleEdge(int start, int end)  
    {  
        Map[start][end] = 0;  
    }  
    //22.2-3  
    void BFS(int s);  
    void Print_Path(int s, int v);  
};  

void Mat_Graph::BFS(int s)  
{  
    int u, v;  
    for(u = 1; u <= n; u++)  
    {  
        color[u] = WHITE;  
        d[u] = 0x7fffffff;  
        Pie[u] = 0;  
    }  
    color[s] = GRAY;  
    d[s] = 0;  
    Pie[s] = 0;  
    while(!Q.empty())Q.pop();  
    Q.push(s);  
    while(!Q.empty())  
    {  
        u = Q.front();Q.pop();  
        for(v = 1; v <= n; v++)  
        {  
            if(Map[u][v] == 0)continue;  
            if(color[v] == WHITE)  
            {  
                color[v] = GRAY;  
                d[v] = d[u] + 1;  
                Pie[v] = u;  
                Q.push(v);  
            }  
        }  
        color[u] = BLACK;  
    }  
}  

void Mat_Graph::Print_Path(int s, int v)  
{  
    BFS(s);  
    if(v == s)  
        cout << s<<' ';  
    else  
    {  
        if(Pie[v] == 0)  
            cout<<"no path from "<<s<<" to "<<v<<" exists."<<endl;  
        else  
        {  
            Print_Path(s, Pie[v]);  
            cout<<v<<' ';  
        }  
    }  
}  

//main.cpp
#include <iostream>  
#include "Mat_Graph.h"  
using namespace std;  
/* 
1 2 
1 5 
2 6 
6 7 
6 3 
3 7 
3 4 
7 8 
7 4 
4 8 
*/  
int main()  
{  
    Mat_Graph *G = new Mat_Graph(8);  
    int i = 0, a, b;  
    for(i = 1; i <= 10; i++)  
    {  
        cin>>a>>b;  
        G->AddDoubleEdge(a,b);  
    }  
    G->BFS(2);  
    for(i = 1; i <= 8; i++)  
        cout<<G->d[i]<<' ';  
    cout<<endl;  
    int s, v;  
    while(cin>>s>>v)  
    {  
        G->Print_Path(s, v);  
        cout<<endl;  
    }  
    delete G;  
    return 0;  
}  

三、图的深度优先搜索(邻接链表)

void Link_Graph::DFS()  
{  
    int u, ceil = 0;  
    //对每个顶点初始化  
    for(u = 1; u <= n; u++)  
    {  
        V[u].color = WHITE;  
        V[u].p =  NULL;  
    }  
    //时间戳初始化  
    time = 0;  
    //依次检索V中的顶点,发现白色顶点时,调用DFS_Visit访问该顶点  
    for(u = 1; u <= n; u++)  
    {  
        if(V[u].color == WHITE)  
        {  
            ceil++;  
            DFS_Visit(u, ceil);  
        }  
    }  
}  

void Link_Graph::DFS_Visit(int u, int ceil)  
{  
    int v;  
    Edge *e;  
    //将u置为灰色  
    V[u].color = GRAY;  
    //使全局变量time增值  
    time++;  
    //将time的新值记录为发现时间  
    V[u].d = time;  
    e = V[u].head;  
    while(e)  
    {  
        v = e->end;  
        //如果顶点为白色  
        if(V[v].color == WHITE)  
        {  
            //递归访问顶点  
            V[v].p = u;  
            DFS_Visit(v, ceil);  
            //树边  
            e->type = TREE;  
        }  
        else if(V[v].color == GRAY)  
        {  
            //反向边  
            e->type = BACK;  
        }  
        else if(V[v].color == BLACK)  
        {  
            //正向边  
            if(V[u].d < V[v].d)  
                e->type = FORWARD;  
            //交叉边  
            else  
                e->type = CROSS;  
        }  
        e = e->next;  
    }  
    //以u为起点的所有边都被探寻后,置u为黑色  
    V[u].color = BLACK;  
    V[u].ceil = ceil;  
    //并将完成时间记录在f[u]中  
    time++;  
    V[u].f = time;  
}  
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值