图的深度优先搜索

/// @file       depth_first_search.cpp
/// @brief      深度优先搜索
/// @copyright  玉涵 updated,2013/11/1

#include <iostream>
#include <vector>
#include <queue>
#include "graphics.h"

using namespace std;

namespace algo
{
    vector<int> DFS_Visit(GraphicsAdjList &g, size_t start_index, vector<int> &d,
                          vector<int> &f, vector<bool> &traversed, int &time);

    /// @brief 深度优先遍历主函数
    /// @param g 邻接表表示的图结构

    void DepthFirstSearch(GraphicsAdjList &g)
    {
        vector<int> d(g.GetVertex().size());    //时间戳d
        vector<int> f(g.GetVertex().size());    //时间戳f
        vector<bool> traversed(g.GetVertex().size(), false);  //着色布尔量
        int time = 0;

        cout << "深度优先遍历:";
        for(size_t i=0; i<g.GetVertex().size(); i++)
        {
            if(!traversed[i])
            {
                vector<int> ids = DFS_Visit(g,i,d,f,traversed,time);
                for(size_t k=0; k<ids.size(); k++)
                {
                    cout << g.GetVertex()[ids[k]] << "[" << d[ids[k]]
                        << "," << f[ids[k]] << "] ";
                }
            }
        }

        cout << endl << "深度优先遍历:";
        vector< pair< int, pair<int, int> > > r;
        for(size_t i=0; i<g.GetVertex().size(); i++)
        {
            r.push_back(make_pair(i, make_pair(d[i], f[i])));
        }

        sort(r.begin(), r.end(), [](pair<int, pair<int, int> > const &p1, pair<int, pair<int, int> > const &p2)
        {
            return p1.second.first < p2.second.first;
        });

        for(size_t i=0; i<r.size(); i++)
        {
            cout << g.GetVertex()[r[i].first] << "[" << r[i].second.first << "," << r[i].second.second << "] ";
        }
    }

    /// @brief              深度优先遍历核心递归函数
    /// @param g            邻接表表示的图
    /// @param start_index  源顶点编号
    /// @param d            时间戳d
    /// @param f            时间戳f
    /// @param traversed    着色布尔量
    /// @param time         全局时间量
    /// @return     返回本次深度优先搜索遍历子树的依次编号
    vector<int> DFS_Visit(GraphicsAdjList &g, size_t start_index, vector<int> &d,
                          vector<int> &f, vector<bool> &traversed, int &time)
    {
        vector<int> this_time_traversed;
        this_time_traversed.push_back(start_index);
        traversed[start_index] = true;
        time++;
        d[start_index] = time;

        for(size_t i=0; i<g.GetVertex().size(); i++)
        {
            if(!traversed[i] && g.IsLinked(start_index, i).first)
            {
                vector<int> v = DFS_Visit(g, i, d, f, traversed, time);
                this_time_traversed.insert(this_time_traversed.end(), v.begin(), v.end());
            }
        }

        time++;
        f[start_index] = time;
        return this_time_traversed;
    }
}

        程序实际上采用了两种方式实现了输出,第一种是在做搜索的时候,把依次遍历到的结点编号导入一个vector<int>中,之后在输出的时候只需要索引该容器即可。另一种方式则是采用了算法导论上提出的时间戳方法,将时间戳d排序然后顺序输出,即是深度遍历顺序,而将f排序输出,则是拓扑排序,拓扑排序以后补充。

        最后感谢川奇兄的coding,川奇兄的指引让我更加熟练操作STL,尽管相对一些诸如Python的语言,C++代码显得既装逼且又臭又长,但是魅力永不减分。

graphics.h请参考之前的博文:图的两种结构封装

http://blog.csdn.net/pediy_yuhan/article/details/13375723

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值