图的深度优先遍历

深度优先遍历

  • 和树的先根遍历类似。
  • 指定从一个顶点v开始访问,并用一个状态表来记录顶点是否被访问。当v被访问时,标记被访问。
  • 当其邻接点未访问时,递归地访问其邻接点以及邻接点的邻接点……直到所有顶点都被访问。

这里写图片描述

  • 例如,上图从顶点 v0 v 0 开始,深度优先遍历图的结果为: v0v1v3v2v5v6v4 v 0 → v 1 → v 3 → v 2 → v 5 → v 6 → v 4
template<class T>
void Graph<T>::DepthFirstSearch(int start)      // 从一个起始点开始递归访问
{
    cout << "->V" << VSet[start].value;
    visited[start] = true;                  // 标记被访问
    for (vector<Vertex<T>>::iterator iter=VSet[start].adj_list.begin();
        iter!= VSet[start].adj_list.end(); ++iter)
    {// 遍历起始点的邻接表
        if (!visited[iter->value])
            DepthFirstSearch(iter->value);      // 若其邻接点没被访问则访问
    }
}

附图的深度优先遍历实现C++

#include<iostream>
#include<vector>
#include<iterator>
using namespace std;

template<class T>
class Vertex {      // 创建一个顶点类
public:
    T value;        // 顶点的关键字值
    vector<Vertex<T>> adj_list;     // 顶点的邻接表
    int weight;     // 顶点之间的权重(相邻顶点的连接权值),存放在邻接顶点中,每个顶点与自身的权值为0

    Vertex(T value = 0) :value(value), weight(0){}  // 默认构造函数

    bool operator < (const Vertex<T> &v) const { return value < v.value; }  // 重载 < 操作符比较两顶点值大小
};

template<class T>
class Graph {       // 创建一个图类
public:
    vector<Vertex<T>> VSet;     // 表示顶点的集合
    Graph(int sz) :size(sz) {}  // 构造函数
    bool* visited;              // 创建布尔类型数组,标记顶点是否被访问
    void Construct();       // 创建(无向)图

    void initVisited(); // 初始化访问数组

    int getsize() { return size; }
    void DepthFirstSearch(int start);   // 指定一个顶点开始深度优先搜索
private:
    int size;                   // 图中顶点的个数
};

template<class T>
void Graph<T>::Construct()
{
    // 创建一个点数组
    Vertex<int> V[] = { Vertex<int>(0), Vertex<int>(1), Vertex<int>(2), Vertex<int>(3),
        Vertex<int>(4), Vertex<int>(5), Vertex<int>(6) };

    // 顶点V0的邻接表
    for (int i = 1;i < 4;i++)
        V[0].adj_list.push_back(V[i]);
    V[0].adj_list[0].weight = 2;    // V0与V1的连接权值
    V[0].adj_list[1].weight = 4;    // V0与V2的连接权值
    V[0].adj_list[2].weight = 1;    // V0与V2的连接权值

    V[1].adj_list.push_back(V[0]);  // 顶点V1的邻接表
    V[1].adj_list.push_back(V[3]);
    V[1].adj_list.push_back(V[4]);
    V[1].adj_list[0].weight = 2;    // V1与V0的连接权值
    V[1].adj_list[1].weight = 3;    // V1与V3的连接权值
    V[1].adj_list[2].weight = 10;   // V1与V4的连接权值

    V[2].adj_list.push_back(V[0]);  // 顶点V2的邻接表
    V[2].adj_list.push_back(V[3]);
    V[2].adj_list.push_back(V[5]);
    V[2].adj_list[0].weight = 4;    // V2与V0的连接权值
    V[2].adj_list[1].weight = 2;    // V2与V3的连接权值
    V[2].adj_list[2].weight = 5;    // V2与V5的连接权值

                                    // 顶点V3的邻接表
    for (int i = 0;i < 7;i++)
    {
        if (i == 3)
            continue;
        V[3].adj_list.push_back(V[i]);
    }
    V[3].adj_list[0].weight = 1;    // V3与V0的连接权值
    V[3].adj_list[1].weight = 3;    // V3与V1的连接权值
    V[3].adj_list[2].weight = 2;    // V3与V2的连接权值
    V[3].adj_list[3].weight = 7;    // V3与V4的连接权值
    V[3].adj_list[4].weight = 8;    // V3与V5的连接权值
    V[3].adj_list[5].weight = 4;    // V3与V6的连接权值

    V[4].adj_list.push_back(V[1]);  // 顶点V4的邻接表
    V[4].adj_list.push_back(V[3]);
    V[4].adj_list.push_back(V[6]);
    V[4].adj_list[0].weight = 10;   // V4与V1的连接权值
    V[4].adj_list[1].weight = 7;    // V4与V3的连接权值
    V[4].adj_list[2].weight = 6;    // V4与V6的连接权值

    V[5].adj_list.push_back(V[2]);  // 顶点V5的邻接表
    V[5].adj_list.push_back(V[3]);
    V[5].adj_list.push_back(V[6]);
    V[5].adj_list[0].weight = 5;    // V5与V2的连接权值
    V[5].adj_list[1].weight = 8;    // V5与V3的连接权值
    V[5].adj_list[2].weight = 1;    // V5与V6的连接权值

    // 顶点V6的邻接表
    for (int i = 3;i < 7;i++)
        V[6].adj_list.push_back(V[i]);
    V[6].adj_list[0].weight = 4;    // V6与V3的连接权值
    V[6].adj_list[1].weight = 6;    // V6与V4的连接权值
    V[6].adj_list[2].weight = 1;    // V6与V5的连接权值

    for (int i = 0;i < 7;i++)       // 将每个点储存在图中的点集VSet中
    {
        VSet.push_back(V[i]);
    }
}

template<class T>
void Graph<T>::initVisited()
{
    visited = new bool[size];
    for (int i = 0;i < size;i++)
    {
        visited[i] = false;     // 初始化访问数组
    }
}

template<class T>
void Graph<T>::DepthFirstSearch(int start)      // 从一个起始点开始递归访问
{
    cout << "->V" << VSet[start].value;
    visited[start] = true;                  // 标记被访问
    for (vector<Vertex<T>>::iterator iter=VSet[start].adj_list.begin();iter!= VSet[start].adj_list.end(); ++iter)
    {// 遍历起始点的邻接表
        if (!visited[iter->value])
            DepthFirstSearch(iter->value);      // 若其邻接点没被访问则访问
    }
}

int main()
{
    Graph<int> G(7);            // 创建一个图对象G
    G.Construct();              // 构造图
    G.initVisited();            // 初始化访问列表
    cout << "The depth-first search on the Graph is: \n";
    G.DepthFirstSearch(0);      // 从第0个顶点开始深度优先遍历访问
    cout << endl;
    system("pause");    
    return 0;
}
  • 运行结果
The depth-first search on the Graph is:
->V0->V1->V3->V2->V5->V6->V4
请按任意键继续. . .
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值