邻接矩阵表示 深度遍历 广度遍历

简介: 邻接矩阵表示 深度遍历 广度遍历

邻接矩阵表示法是一种图的表示方法,其中每个顶点都有一个唯一的索引,而每条边则由两个顶点之间的连接确定。深度优先遍历(DFS)和广度优先遍历(BFS)是两种常用的图遍历算法。

1. 深度优先遍历(DFS):

深度优先遍历从根节点开始,沿着一条路径尽可能深入地访问节点,直到到达叶子节点。然后回溯到上一个节点,继续访问其他未访问过的节点。这个过程一直持续到所有节点都被访问过为止。

在邻接矩阵表示法中,可以使用递归或栈来实现深度优先遍历。以下是使用栈实现的示例代码:

#include <iostream>
#include <stack>
using namespace std;
void dfs(int matrix[][4], int start, bool visited[]) {
    stack<int> s;
    s.push(start);
    visited[start] = true;
    while (!s.empty()) {
        int node = s.top();
        s.pop();
        cout << node << " ";
        for (int i = 0; i < 4; i++) {
            if (matrix[node][i] == 1 && !visited[i]) {
                s.push(i);
                visited[i] = true;
            }
        }
    }
}
int main() {
    int matrix[4][4] = {
        {0, 1, 1, 0},
        {1, 0, 0, 1},
        {1, 0, 0, 1},
        {0, 1, 1, 0}
    };
    bool visited[4] = {false};
    dfs(matrix, 0, visited);
    return 0;
}

 

2. 广度优先遍历(BFS):

广度优先遍历从根节点开始,首先访问所有与根节点直接相连的节点,然后再访问这些节点的邻居节点,以此类推。这个过程一直持续到所有节点都被访问过为止。

在邻接矩阵表示法中,可以使用队列来实现广度优先遍历。以下是使用队列实现的示例代码:

#include <iostream>
#include <queue>
using namespace std;
void bfs(int matrix[][4], int start, bool visited[]) {
    queue<int> q;
    q.push(start);
    visited[start] = true;
    while (!q.empty()) {
        int node = q.front();
        q.pop();
        cout << node << " ";
        for (int i = 0; i < 4; i++) {
            if (matrix[node][i] == 1 && !visited[i]) {
                q.push(i);
                visited[i] = true;
            }
        }
    }
}
int main() {
    int matrix[4][4] = {
        {0, 1, 1, 0},
        {1, 0, 0, 1},
        {1, 0, 0, 1},
        {0, 1, 1, 0}
    };
    bool visited[4] = {false};
    bfs(matrix, 0, visited);
    return 0;
}

 

3. 邻接矩阵表示 深度遍历 广度遍历

代码如下:

#include <iostream>
#include <stack>
#include <queue>
using namespace std;
#define MaxInt  32767
#define MVNum 100
typedef char VerTexType;
typedef int ArcType;
//邻接矩阵
typedef  struct {
    VerTexType  vexs[MVNum];  /*存储顶点元素*/
    ArcType arcs[MVNum][MVNum];
    /*各顶点之间的关系或权值*/
    int  vexnum, arcnum; /*顶点数,边(或弧)的个数*/
}MGraph;
int visited[MVNum];
int visitedBFS[MVNum];
stack<VerTexType> mystack;
queue<VerTexType> myqueue;
//函数声明
void PrintVisited();
int LocateVex(MGraph& G, VerTexType v); //函数定义
void CreateMGraph(MGraph& G);
void DFS(MGraph& G, VerTexType v);
void BFS(MGraph& G, VerTexType v);
void TestDemoGraph();
//函数定义
void  CreateMGraph(MGraph& G) {
    int i = 0, j = 0, k = 0;
    cout << "输入顶点个数:";
    cin >> G.vexnum;
    cout << "输入边的个数:";
    cin >> G.arcnum;
    for (i = 0; i < G.vexnum; i++) {
        cout << "输入第" << i + 1 << "个顶点的名称:";
        cin >> G.vexs[i];
    }
    for (i = 0; i < G.vexnum; ++i)         //初始化邻接矩阵,
        for (j = 0; j < G.vexnum; ++j)
            G.arcs[i][j] = 0;
    cout << "输入边依附的顶点 ,如 a b " << endl;
    VerTexType v1, v2;
    for (k = 0; k < G.arcnum; ++k) {              //构造邻接矩阵
        cout << "请输入第" << (k + 1) << "条边依附的顶点及权值:";
        cin >> v1 >> v2;                //输入一条边依附的顶点及权值
        i = LocateVex(G, v1);   //函数调用
        j = LocateVex(G, v2);   //确定v1和v2在G中的位置,即顶点数组的下标
        if (i == -1 || j == -1) {
            cout << "顶点名称错误" << endl;
            k--;
            continue;
        }
        G.arcs[i][j] = 1;               //边<v1, v2>的值为1
        G.arcs[j][i] = G.arcs[i][j];            //置<v1, v2>的对称边<v2, v1>的权值为w
    }//for
}
int LocateVex(MGraph& G, VerTexType v) { //函数定义
    //确定点v在G中的位置
    for (int i = 0; i < G.vexnum; ++i)
        if (G.vexs[i] == v)
            return i;
    return -1;
}//LocateVex
void PrintVexArc(MGraph& G) {
    int i = 0, j = 0;
    cout << "顶点列表:" << endl;
    for (i = 0; i < G.vexnum; i++) {
        cout << "\t" << G.vexs[i];
    }
    cout << endl << "邻接矩阵:" << endl;
    for (i = 0; i < G.vexnum; i++) {
        for (j = 0; j < G.vexnum; j++) {
            cout << "\t" << G.arcs[i][j];
        }
        cout << endl;
    }
}
void PrintVisited() {
    for (int i = 0; i < 6; i++) cout << visited[i] << "\t"; cout << endl;
}
void PrintVisitedBFS() {
    for (int i = 0; i < 6; i++) cout << visitedBFS[i] << "\t"; cout << endl;
}
void DFS(MGraph& G, VerTexType v) {  //从v点开始深度遍历
    int index = LocateVex(G, v);
    if (index == -1) {
        cout << "没有这个结点" << v << endl;
        return;
    }
    if (visited[index] == 1) {  //已经访问过了,就返回。
        return;
    }
    //没有访问过,直接标记访问,操作,没有访问过的邻接点入栈
    visited[index] = 1; //标记当前结点已经访问过了
    cout << v << "\t"; //访问当前结点V,对该结点进行操作,直接输出。
    PrintVisited();
    int j = 0;
    for (j = G.vexnum; j >= 0; j--) {
        if (G.arcs[index][j] == 1 && visited[j] == 0) {
            mystack.push(G.vexs[j]);
        }
    }
    while (!mystack.empty()) {
        VerTexType vex = mystack.top();
        mystack.pop();
        DFS(G, vex);
    }
}
void BFS(MGraph& G, VerTexType v) {   //从v点开始广度遍历
    int index = LocateVex(G, v);
    if (index == -1) {
        cout << "没有这个结点" << v << endl;
        return;
    }
    if (visitedBFS[index] == 1) {
        return;
    }
    //没有被访问过,
    visitedBFS[index] = 1;
    cout << v << "\t";
    PrintVisitedBFS();
    for (int i = 0; i < G.vexnum; i++) {
        if (G.arcs[index][i] == 1 && visitedBFS[i] == 0) {
            //  cout<<"["<<index<<"]["<<i<<"]="<<G.vexs[i]<<endl;
            myqueue.push(G.vexs[i]);
        }
    }
    while (!myqueue.empty()) {
        VerTexType vex = myqueue.front();
        myqueue.pop();
        //cout<<"pop-->"<<vex<<endl;
        BFS(G, vex);
    }
}
void TestDemoGraph() {
    MGraph G;
    CreateMGraph(G);
    PrintVexArc(G);
    cout << "DFS--->" << endl;
    DFS(G, 'b');
    cout << "BFS--->" << endl;
    BFS(G, 'b');
}
int main()
{
    TestDemoGraph();
    return 0;
}
/*
6
8
a
b
c
d
e
f
ab
af
ae
bc
bd
fd
ed
cd
*/

 

运行结果:

加油各位!!

目录
相关文章
|
7月前
|
算法
落叶归根:递归思想在二叉树叶子节点类问题中的妙用
落叶归根:递归思想在二叉树叶子节点类问题中的妙用
77 1
|
6月前
二叉树中的深度搜索
二叉树中的深度搜索
|
6月前
|
算法
数据结构和算法学习记录——层序遍历(层次遍历)、二叉树遍历的应用(输出二叉树中的叶节点、求二叉树的高度、二元运算表达式树及其遍历、由两种遍历序列确定二叉树)
数据结构和算法学习记录——层序遍历(层次遍历)、二叉树遍历的应用(输出二叉树中的叶节点、求二叉树的高度、二元运算表达式树及其遍历、由两种遍历序列确定二叉树)
61 0
|
算法
用递归的思想实现二叉树前、中、后序迭代遍历
用递归的思想实现二叉树前、中、后序迭代遍历
75 1
|
7月前
|
算法 索引
邻接矩阵表示 深度遍历 广度遍历
邻接矩阵表示 深度遍历 广度遍历
51 0
|
7月前
|
算法
树的深度优先和广度优先
树的深度优先和广度优先
47 0
|
算法
【算法】通过递归和非递归实现树的前中后序以及广度优先搜索和深度优先搜索
【算法】通过递归和非递归实现树的前中后序以及广度优先搜索和深度优先搜索
137 0
|
存储
图的深度遍历和广度遍历
图的深度遍历和广度遍历
103 0
|
存储 算法
【数据结构】图以及图的遍历(深度遍历和广度遍历)
【数据结构】图以及图的遍历(深度遍历和广度遍历)
194 0
|
算法
算法系列-多叉树的遍历
在内卷潮流的席卷下,身为算法小白的我不得不问自己,是否得踏上征程,征服这座巍巍高山。 从零开始,终点不知何方,取决于自己可以坚持多久。 希望你可以和我一样,克服恐惧,哪怕毫无基础,哪怕天生愚钝,依然选择直面困难。