图的深度优先遍历

图的迭代

//
// Created by liuyubobobo on 9/22/16.
//

#ifndef INC_05_DFS_AND_COMPONENTS_DENSEGRAPH_H
#define INC_05_DFS_AND_COMPONENTS_DENSEGRAPH_H

#include <iostream>
#include <vector>
#include <cassert>

using namespace std;

// 稠密图 - 邻接矩阵
class DenseGraph{

private:
    int n, m;
    bool directed;
    vector<vector<bool>> g;

public:
    DenseGraph( int n , bool directed ){
        this->n = n;
        this->m = 0;
        this->directed = directed;
        for( int i = 0 ; i < n ; i ++ )
            g.push_back( vector<bool>(n, false) );
    }

    ~DenseGraph(){

    }

    int V(){ return n;}
    int E(){ return m;}

    void addEdge( int v , int w ){

        assert( v >= 0 && v < n );
        assert( w >= 0 && w < n );

        if( hasEdge( v , w ) )
            return;

        g[v][w] = true;
        if( !directed )
            g[w][v] = true;

        m ++;
    }

    bool hasEdge( int v , int w ){
        assert( v >= 0 && v < n );
        assert( w >= 0 && w < n );
        return g[v][w];
    }

    void show(){

        for( int i = 0 ; i < n ; i ++ ){
            for( int j = 0 ; j < n ; j ++ )
                cout<<g[i][j]<<"\t";
            cout<<endl;
        }
    }

    class adjIterator{
    private:
        DenseGraph &G;
        int v;
        int index;
    public:
        adjIterator(DenseGraph &graph, int v): G(graph){
            this->v = v;
            this->index = -1;
        }

        int begin(){

            index = -1;
            return next();
        }

        int next(){
            for( index += 1 ; index < G.V() ; index ++ )
                if( G.g[v][index] )
                    return index;
            return -1;
        }

        bool end(){
            return index >= G.V();
        }
    };
};

#endif //INC_05_DFS_AND_COMPONENTS_DENSEGRAPH_H

//
// Created by liuyubobobo on 9/22/16.
//

#ifndef INC_05_DFS_AND_COMPONENTS_SPARSEGRAPH_H
#define INC_05_DFS_AND_COMPONENTS_SPARSEGRAPH_H

#include <iostream>
#include <vector>
#include <cassert>

using namespace std;

// 稀疏图 - 邻接表
class SparseGraph{

private:
    int n, m;
    bool directed;
    vector<vector<int>> g;

public:
    SparseGraph( int n , bool directed ){
        this->n = n;
        this->m = 0;
        this->directed = directed;
        for( int i = 0 ; i < n ; i ++ )
            g.push_back( vector<int>() );
    }

    ~SparseGraph(){

    }

    int V(){ return n;}
    int E(){ return m;}

    void addEdge( int v, int w ){

        assert( v >= 0 && v < n );
        assert( w >= 0 && w < n );

        g[v].push_back(w);
        if( v != w && !directed )
            g[w].push_back(v);

        m ++;
    }

    bool hasEdge( int v , int w ){

        assert( v >= 0 && v < n );
        assert( w >= 0 && w < n );

        for( int i = 0 ; i < g[v].size() ; i ++ )
            if( g[v][i] == w )
                return true;
        return false;
    }

    void show(){

        for( int i = 0 ; i < n ; i ++ ){
            cout<<"vertex "<<i<<":\t";
            for( int j = 0 ; j < g[i].size() ; j ++ )
                cout<<g[i][j]<<"\t";
            cout<<endl;
        }
    }

    class adjIterator{
    private:
        SparseGraph &G;
        int v;
        int index;
    public:
        adjIterator(SparseGraph &graph, int v): G(graph){
            this->v = v;
            this->index = 0;
        }

        int begin(){
            index = 0;
            if( G.g[v].size() )
                return G.g[v][index];
            return -1;
        }

        int next(){
            index ++;
            if( index < G.g[v].size() )
                return G.g[v][index];
            return -1;
        }

        bool end(){
            return index >= G.g[v].size();
        }
    };
};

#endif //INC_05_DFS_AND_COMPONENTS_SPARSEGRAPH_H

  遍历操作类

//
// Created by liuyubobobo on 9/22/16.
//

#ifndef INC_05_DFS_AND_COMPONENTS_COMPONENTS_H
#define INC_05_DFS_AND_COMPONENTS_COMPONENTS_H

#include <iostream>
#include <cassert>
using namespace std;

template <typename Graph>
class Component{

private:
    Graph &G;
    bool *visited;
    int ccount;
    int *id;

    void dfs( int v ){

        visited[v] = true;
        id[v] = ccount;
        typename Graph::adjIterator adj(G, v);
        for( int i = adj.begin() ; !adj.end() ; i = adj.next() ){
            if( !visited[i] )
                dfs(i);
        }
    }

public:
    Component(Graph &graph): G(graph){

        visited = new bool[G.V()];
        id = new int[G.V()];
        ccount = 0;
        for( int i = 0 ; i < G.V() ; i ++ ){
            visited[i] = false;
            id[i] = -1;
        }

        for( int i = 0 ; i < G.V() ; i ++ )
            if( !visited[i] ){
                dfs(i);
                ccount ++;
            }
    }

    ~Component(){
        delete[] visited;
        delete[] id;
    }

    int count(){
        return ccount;
    }

    bool isConnected( int v , int w ){
        assert( v >= 0 && v < G.V() );
        assert( w >= 0 && w < G.V() );
        return id[v] == id[w];
    }
};

#endif //INC_05_DFS_AND_COMPONENTS_COMPONENTS_H

  

时间: 2024-10-08 23:10:02

图的深度优先遍历的相关文章

图的深度优先遍历--邻接表实现

这里用邻接表实现图的深度优先遍历,采用递归实现. #include<iostream> using namespace std; #define VERTEXNUM 5//结点数 struct edgenode { int to; int weight; // 边的权值 edgenode *next; }; struct vnode { int from; edgenode *first; }; void createGraph(vnode *adjilist, int start, int

图的深度优先遍历(DFS) c++ 非递归实现

深搜算法对于程序员来讲是必会的基础,不仅要会,更要熟练.ACM竞赛中,深搜也牢牢占据着很重要的一部分.本文用显式栈(非递归)实现了图的深度优先遍历,希望大家可以相互学习. 栈实现的基本思路是将一个节点所有未被访问的“邻居”(即“一层邻居节点”)踹入栈中“待用”,然后围绕顶部节点猛攻,每个节点被访问后被踹出.读者可以自己画图分析一下,难度并不大. 代码写的比较随意,仅供参考.~ #include <iostream> #include <stack> using namespace

以邻接表作为存储结构的图的深度优先遍历和广度优先遍历(c++版)

一.图的存储 用邻接表法存储图,存储结构分为两部分,一部分为存储图的所有顶点的数组,另一部分为挂载在数组的每个元素后面的用来表示顶点的邻接点的链表. 1.存储顶点的结构单元为: class vnode { public: string nodename; bool visted;//进行图的遍历时用于标记图是否被访问过 node *next; vnode() { visted = false; next = NULL; } }; 链表的结构单元为: class node { public: st

图的深度优先遍历DFS

图的深度优先遍历是树的前序遍历的应用,其实就是一个递归的过程,我们人为的规定一种条件,或者说一种继续遍历下去的判断条件,只要满足我们定义的这种条件,我们就遍历下去,当然,走过的节点必须记录下来,当条件不满足后,我们就return,回到上一层,换个方向继续遍历. 模板: 1 //邻接矩阵存储方式 2 bool visited[MAX]; 3 void dfs(MGraph G,int i) 4 { 5 int j; 6 visited[i]=true; 7 cout<<G.vex[i]<&

基于邻接表存储的图的深度优先遍历和广度优先遍历

一.深度优先遍历是连通图的一种遍历策略.其基本思想如下: 设x是当前被访问顶点,在对x做过访问标记后,选择一条从x出发的未检测过的边(x,y).若发现顶点y已访问过,则重新选择另一条从x出发的未检测过的边,否则沿边(x,y)到达未曾访问过的y,对y访问并将其标记为已访问过:然后从y开始搜索,直到搜索完从y出发的所有路径,即访问完所有从y出发可达的顶点之后,才回溯到顶点x,并且再选择一条从x出发的未检测过的边.上述过程直至从x出发的所有边都已检测过为止. 例如下图中: 1.从0开始,首先找到0的关

基于邻接矩阵存储的图的深度优先遍历和广度优先遍历

图的存储结构相比较线性表与树来说就复杂很多,对于线性表来说,是一对一的关系,所以用数组或者链表均可简单存放.树结构是一对多的关系,所以我们要将数组和链表的特性结合在一起才能更好的存放. 那么我们的图,是多对多的情况,另外图上的任何一个顶点都可以被看作是第一个顶点,任一顶点的邻接点之间也不存在次序关系. 仔细观察以下几张图,然后深刻领悟一下: 因为任意两个顶点之间都可能存在联系,因此无法以数据元素在内存中的物理位置来表示元素之间的关系(内存物理位置是线性的,图的元素关系是平面的). 如果用多重链表

算法题——图的深度优先遍历

原理和方法可以参考: 图的深度优先遍历 教科书上的C代码,递归: 1 //教科书方法,邻接表 2 bool visited[MAX]; 3 void visitFunc(int v); 4 5 void dfsTraverse(Graph G) 6 { 7 for(v = 0; v < G.vexnum; ++v) //初始化访问标识为false 8 visited[v] = false; 9 for(v = 0; v < G.vexnum; ++v) //深搜 10 if(!visited[

PTA 邻接矩阵存储图的深度优先遍历

6-1 邻接矩阵存储图的深度优先遍历(20 分) 试实现邻接矩阵存储图的深度优先遍历. 函数接口定义: void DFS( MGraph Graph, Vertex V, void (*Visit)(Vertex) ); 其中MGraph是邻接矩阵存储的图,定义如下: typedef struct GNode *PtrToGNode; struct GNode{ int Nv; /* 顶点数 */ int Ne; /* 边数 */ WeightType G[MaxVertexNum][MaxVe

数据结构 - 图的深度优先遍历(C++)

Boolean visited[MAX_VERTEX_NUM]; //访问标志数组. Status (*VisitFunc)(int v); //VisitFunc是访问函数,对图的每个顶点调用该函数. void DFSTraverse (Graph G, Status(*Visit)(int v)) //图的深度优先遍历. { VisitFunc = Visit; for(v=0; v<G.vexnum; ++v) visited[v] = FALSE; //访问标志数组初始化. for(v=

图的深度优先遍历(DFS)—递归算法

实验环境:win10, DEV C++5.11 实验要求: 实现图的深度优先遍历 实验代码: #include <iostream> #define maxSize 255 #include "stdlib.h" /* run this program using the console pauser or add your own getch, system("pause") or input loop */ /*the definition of s