【DFS and BFS】

Preface

最近在看数据结构与算法,当前进度到DFS和BFS。
网上内容尤其是代码内容鱼龙混杂,因此mark一下正确可运行的DFS和BFS。亲测可用,放心食用。

代码内容借鉴:
https://www.cnblogs.com/Luoters/p/12033473.html
基于该代码,修改了部分语法错误。

Breief Introduction

DFS: Depth First Search 深度优先搜索
BFS: Breadth First Search 广度优先搜索

DFS和BFS是两种图遍历的方式。二者都是按照约定规则对图进行遍历。
DFS的主要实现是通过递归和回溯。与树中的前序、中序、遍历相似,按既定规则一条路走到黑,若此路不通则退回到有其他方式的路上继续遍历,因此会遍历所有的可能路径,时间消耗更多一些。
BFS的主要实现靠逻辑遍历。与树中的层序遍历类似,按既定规则把每个元素的可能路径探索一遍,一层一层进行,这其中需要新建一个队列帮助,因此空间消耗更多一些。
另外,BFS的优势还在于,能够连续找到与同一元素关联的数据。

图的表示主要有邻接矩阵和邻接表两种,因此分别基于图的这两种表示方法实现DFS和BFS。
多说无益,直接上代码。

Code

Based on Adjacent Matrix

基于邻接矩阵无向图,分别实现DFSBFS

DFS Based on Adjacent Matrix

#include <iostream>
#define MAXNUM 10
using namespace std;
typedef struct
{
    int vnum;
    int anum;
    char ver[MAXNUM];
    char arc[MAXNUM][MAXNUM];
}MGraph;
int Location(MGraph& G, char e)
{
    for (int i = 0; i < G.vnum; i++)
    {
        if (G.ver[i] == e)
            return i;
    }
    return -1;
}
bool CreateGraph(MGraph& G, int vnum, int anum, char v[], char a[])
{
    G.vnum = vnum;
    G.anum = anum;
    for (int i = 0; i < G.vnum; i++)
    {
        G.ver[i] = v[i];
    }
    for (int i = 0; i < G.vnum; i++)
    {
        for (int j = 0; j < G.vnum; j++)
        {
            G.arc[i][j] = 0;
        }
    }
    int t = 0;
    for (int i = 0; i < G.vnum; i++)
    {
        char m = a[t++];
        char n = a[t++];
        t++;
        t++;
        int p = Location(G, m);
        int q = Location(G, n);
        G.arc[p][q] = 1;
        G.arc[q][p] = 1;
    }
    return true;
}
int FirstAdjVex(MGraph& G, int i)
{
    for (int j = 0; j < G.vnum; j++)
    {
        if (G.arc[i][j] == 1)
        {
            return j;
        }
    }
    return -1;
}
int NextAdjVex(MGraph& G, int i, int j)
{
    for (int k = j+1; k < G.vnum; k++)
    {
        if (G.arc[i][k] == 1)
        {
            return k;
        }
    }
    return -1;
}
int visited[MAXNUM];
void DFS(MGraph& G, int i)
{
    visited[i] = 1;
    cout << G.ver[i] << endl;
    int k = FirstAdjVex(G, i);
    cout << "first " << G.ver[i] << " to " << G.ver[k] << endl;
    while (k != -1)
    {
        if(visited[k] == 0)
        {
            cout << G.ver[k] << endl;
            visited[k] = 1;
            DFS(G, k);
        }
        k = NextAdjVex(G, i, k);
        cout << "next " << G.ver[i] << " to " << G.ver[k] << endl;
    }
}
void DFSTraverse(MGraph& G)
{
    for (int i = 0; i < G.vnum; i++)
    {
        visited[i] = 0;
    }
    for (int i = 0; i < G.vnum; i++)
    {
        if (visited[i] == 0)
        {
            DFS(G, i);
        }
    }
}
int main()
{
    char v[] = "abcdef";
    char a[] = "ab, ac, ad, be, ce, df";
    MGraph G;
    CreateGraph(G, 6, 6, v, a);
    DFSTraverse(G);
    return 0;
}

输出结果如下:

 a
first a to b
b
b
first b to a
next b to e
e
e
first e to b
next e to c
c
c
first c to a
next c to e
next c to  
next e to  
next b to  
next a to c
next a to d
d
d
first d to a
next d to f
f
f
first f to d
next f to  
next d to  
next a to  

BFS Based on Adjacent Matrix

#include <iostream>
#define MAXNUM 10
using namespace std;

typedef struct
{
    int vnum;
    int anum;
    char ver[MAXNUM];
    char arc[MAXNUM][MAXNUM];
}MGraph;
int Location(MGraph& G, char e)
{
    for (int i = 0; i < G.vnum; i++)
    {
        if (G.ver[i] == e)
            return i;
    }
    return -1;
}
bool CreateGraph(MGraph& G, int vnum, int anum, char v[], char a[])
{
    G.vnum = vnum;
    G.anum = anum;
    for (int i = 0; i < G.vnum; i++)
    {
        G.ver[i] = v[i];
    }
    for (int i = 0; i < G.vnum; i++)
    {
        for (int j = 0; j < G.vnum; j++)
        {
            G.arc[i][j] = 0;
        }
    }
    int t = 0;
    for (int i = 0; i < G.vnum; i++)
    {
        char m = a[t++];
        char n = a[t++];
        t++;
        t++;
        int p = Location(G, m);
        int q = Location(G, n);
        G.arc[p][q] = 1;
        G.arc[q][p] = 1;
    }
    return true;
}
int FirstAdjVex(MGraph& G, int i)
{
    for (int j = 0; j < G.vnum; j++)
    {
        if (G.arc[i][j] == 1)
        {
            return j;
        }
    }
    return -1;
}
int NextAdjVex(MGraph& G, int i, int j)
{
    for (int k = j+1; k < G.vnum; k++)
    {
        if (G.arc[i][k] == 1)
        {
            return k;
        }
    }
    return -1;
}

typedef struct QNode
{
    char data;
    QNode* next;
}QNode, *QueuePtr;
typedef struct
{
    QueuePtr first;
    QueuePtr last;
}LinkQueue;
bool InitQueue(LinkQueue& Q)
{
    Q.first = (QNode*)malloc(sizeof(QNode));
    if (!Q.first) return false;
    Q.first->next = NULL;
    Q.last = Q.first;
    return true;
}
bool EnQueue(LinkQueue& Q, char e)
{
    auto q = (QNode*)malloc(sizeof(QNode));
    if (!q) return false;
    q->data = e;
    q->next = NULL;
    Q.last->next = q;
    Q.last = q;
    return true;
}
bool DeQueue(LinkQueue& Q, char& e)
{
    if (Q.first == Q.last)
        return false;
    auto q = Q.first->next;
    if (q != NULL)
    {
        Q.first->next = q->next;
        e = q->data;
    }
    if(q == Q.last)
    {
        Q.last = Q.first;
    }
    return true;
}
bool EmptyQueue(LinkQueue& Q)
{
    if (Q.first == Q.last)
        return true;
    return false;
}

int visited[MAXNUM];
void BFS(MGraph& G)
{
    for (int i = 0; i < G.vnum; i++)
    {
        visited[i] = 0;
    }
    LinkQueue Q;
    InitQueue(Q);
    for (int i = 0; i < G.vnum; i++)
    {
        if (visited[i] == 0)
        {
            EnQueue(Q, G.ver[i]);
            visited[i] = 1;
            cout << G.ver[i] << endl;
            while (!EmptyQueue(Q))
            {
                char e;
                DeQueue(Q, e);
                int v = Location(G, e);
                int w = FirstAdjVex(G, v);
                while (w != -1)
                {
                    if (visited[w] == 0)
                    {
                        EnQueue(Q, G.ver[w]);
                        visited[w] = 1;
                        cout << G.ver[w] << endl;
                    }
                    w = NextAdjVex(G, v, w);
                }
            }
        }
    }
    return;
}
int main()
{
    char v[] = "abcdef";
    char a[] = "ab, ac, ad, be, ce, df";
    MGraph G;
    CreateGraph(G, 6, 6, v, a);
    BFS(G);
    return 0;
}

Based on Adjacent List

基于邻接表无向图,分别实现DFSBFS

DFS Based on Adjacent List

#include <iostream>
#define MAXNUM 10
using namespace std;
typedef struct ANode
{
    int AdjVex;
    ANode* next;
}ANode;
typedef struct VNode
{
    char data;
    ANode *firstArc;
};
typedef struct
{
    int vnum;
    int anum;
    VNode vex[MAXNUM];
}ALGraph;
int Location(ALGraph& G,char e)
{
    for (int i = 0; i < G.vnum; i++)
    {
        if (G.vex[i].data == e)
            return i;
    }
    return -1;
}
bool CreateGraph(ALGraph& G, int vnum, int anum, char v[], char a[])
{
    G.vnum = vnum;
    G.anum = anum;
    for (int i = 0; i < G.vnum; i++)
    {
        G.vex[i].data = v[i];
        G.vex[i].firstArc = NULL;
    }
    int t = 0;
    for (int i = 0; i < G.vnum; i ++)
    {
        char m = a[t++];
        char n = a[t++];
        t++;
        t++;
        int p = Location(G, m);
        int q = Location(G, n);
        ANode *p1, *p2, *p3;
        p1 = (ANode*)malloc(sizeof(ANode));
        p1->AdjVex = p;
        p1->next = NULL;
        if (G.vex[q].firstArc == NULL)
        {
            G.vex[q].firstArc = p1;
        }
        else
        {
            p3 = G.vex[q].firstArc;
            while (p3->next)
            {
                p3 = p3->next;
            }
            p3->next = p1;
        }
        p2 = (ANode*)malloc(sizeof(ANode));
        p2->AdjVex = q;
        p2->next = NULL;
        if (G.vex[p].firstArc == NULL)
        {
            G.vex[p].firstArc = p2;
        }
        else
        {
            p3 = G.vex[p].firstArc;
            while(p3->next)
            {
                p3 = p3->next;
            }
            p3->next = p2;
        }
    }
    return true;
}
int FirstAdjVex(ALGraph& G, int i)
{
    if (G.vex[i].firstArc)
        return G.vex[i].firstArc->AdjVex;
    return -1;
}
int NextAdjVex(ALGraph& G, int i, int j)
{
    auto p = G.vex[i].firstArc;
    if (p->AdjVex == j and p->next)
        return p->next->AdjVex;
    else if(p->next)
        p = p->next;
    return -1;
}
int visited[MAXNUM];
void DFS(ALGraph &G, int i)
{
    visited[i] = 1;
    cout << G.vex[i].data << endl;
    int k = FirstAdjVex(G, i);
    cout << "first " << G.vex[i].data << " to " << G.vex[k].data << endl;
    while (k != -1)
    {
        if(visited[k] == 0)
        {
            cout << G.vex[k].data << endl;
            visited[k] = 1;
            DFS(G, k);
        }
        k = NextAdjVex(G, i, k);
        cout << "next " << G.vex[i].data << " to " << G.vex[k].data << endl;
    }
}
void DFSTraverse(ALGraph & G)
{
    for (int i = 0; i < G.vnum; i++)
    {
        visited[i] = 0;
    }
    for (int i = 0; i < G.vnum; i++)
    {
        if (visited[i] == 0)
        {
            DFS(G, i);
        }
    }
}
int main()
{
    char v[] = "abcdef";
    char a[] = "ab, ac, ad, be, ce, df";
    ALGraph G;
    CreateGraph(G, 6, 6, v, a);
    // BFS(G);
    DFSTraverse(G);
    return 0;
}

输出结果如下:

a
first a to b
b
b
first b to a
next b to e
e
e
first e to b
next e to c
c
c
first c to a
next c to e
next c to L
next e to L
next b to L
next a to c
next a to L
d
first d to a
next d to f
f
f
first f to d
next f to L
next d to L

BFS Based on Adjacent List

#include <iostream>
#define MAXNUM 10
using namespace std;

 typedef struct ANode
{
    int AdjVex;
    ANode* next;
}ANode;
typedef struct VNode
{
    char data;
    ANode *firstArc;
};
typedef struct
{
    int vnum;
    int anum;
    VNode vex[MAXNUM];
}ALGraph;
int Location(ALGraph& G,char e)
{
    for (int i = 0; i < G.vnum; i++)
    {
        if (G.vex[i].data == e)
            return i;
    }
    return -1;
}
bool CreateGraph(ALGraph& G, int vnum, int anum, char v[], char a[])
{
    G.vnum = vnum;
    G.anum = anum;
    for (int i = 0; i < G.vnum; i++)
    {
        G.vex[i].data = v[i];
        G.vex[i].firstArc = NULL;
    }
    int t = 0;
    for (int i = 0; i < G.vnum; i ++)
    {
        char m = a[t++];
        char n = a[t++];
        t++;
        t++;
        int p = Location(G, m);
        int q = Location(G, n);
        ANode *p1, *p2, *p3;
        p1 = (ANode*)malloc(sizeof(ANode));
        p1->AdjVex = p;
        p1->next = NULL;
        if (G.vex[q].firstArc == NULL)
        {
            G.vex[q].firstArc = p1;
        }
        else
        {
            p3 = G.vex[q].firstArc;
            while (p3->next)
            {
                p3 = p3->next;
            }
            p3->next = p1;
        }
        p2 = (ANode*)malloc(sizeof(ANode));
        p2->AdjVex = q;
        p2->next = NULL;
        if (G.vex[p].firstArc == NULL)
        {
            G.vex[p].firstArc = p2;
        }
        else
        {
            p3 = G.vex[p].firstArc;
            while(p3->next)
            {
                p3 = p3->next;
            }
            p3->next = p2;
        }
    }
    return true;
}
int FirstAdjVex(ALGraph& G, int i)
{
    if (G.vex[i].firstArc)
        return G.vex[i].firstArc->AdjVex;
    return -1;
}
int NextAdjVex(ALGraph& G, int i, int j)
{
    auto p = G.vex[i].firstArc;
    if (p->AdjVex == j and p->next)
        return p->next->AdjVex;
    else if(p->next)
        p = p->next;
    return -1;
}

typedef struct QNode
{
    char data;
    QNode* next;
}QNode, *QueuePtr;
typedef struct
{
    QueuePtr first;
    QueuePtr last;
}LinkQueue;
bool InitQueue(LinkQueue& Q)
{
    Q.first = (QNode*)malloc(sizeof(QNode));
    if (!Q.first) return false;
    Q.first->next = NULL;
    Q.last = Q.first;
    return true;
}
bool EnQueue(LinkQueue& Q, char e)
{
    auto q = (QNode*)malloc(sizeof(QNode));
    if (!q) return false;
    q->data = e;
    q->next = NULL;
    Q.last->next = q;
    Q.last = q;
    return true;
}
bool DeQueue(LinkQueue& Q, char& e)
{
    if (Q.first == Q.last)
        return false;
    auto q = Q.first->next;
    if (q != NULL)
    {
        Q.first->next = q->next;
        e = q->data;
    }
    if(q == Q.last)
    {
        Q.last = Q.first;
    }
    return true;
}
bool EmptyQueue(LinkQueue& Q)
{
    if (Q.first == Q.last)
        return true;
    return false;
}

int visited[MAXNUM];
void BFS(ALGraph& G)
{
    for (int i = 0; i < G.vnum; i++)
    {
        visited[i] = 0;
    }
    LinkQueue Q;
    InitQueue(Q);
    for (int i = 0; i < G.vnum; i++)
    {
        if (visited[i] == 0)
        {
            EnQueue(Q, G.vex[i].data);
            visited[i] = 1;
            cout << G.vex[i].data << endl;
            while (!EmptyQueue(Q))
            {
                char e;
                DeQueue(Q, e);
                int v = Location(G, e);
                int w = FirstAdjVex(G, v);
                while (w != -1)
                {
                    if (visited[w] == 0)
                    {
                        EnQueue(Q, G.vex[w].data);
                        visited[w] = 1;
                        cout << G.vex[w].data << endl;
                    }
                    w = NextAdjVex(G, v, w);
                }
            }
        }
    }
    return;
}
int main()
{
    char v[] = "abcdef";
    char a[] = "ab, ac, ad, be, ce, df";
    ALGraph G;
    CreateGraph(G, 6, 6, v, a);
    BFS(G);
    // DFSTraverse(G);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值