图的遍历

1.DFS(深度优先遍历)
DFS:假设图g的每一个节点都未被访问过,从顶点V出发依次访问它的临接顶点W,若W无临接节点则返回V并访问下一个临接节点W2。直到所有节点都被访问到。

a.临接表的DFS
思路:在有向图临接表中,我们知道每一个顶点V后都依次连着它的临接顶点,那我们只要依次访问就好,并用递归来实现遍历全部。

//邻接表实现图的建立和DFS
#include<iostream>
using namespace std;
typedef char VertexType;

int Visited[1000] = {0};//用来判断顶点是否已经访问过。
struct EdgeNode
{
    int Adjv;
    struct EdgeNode * next;
};
struct VertexNode
{
    VertexType Vertex;
    EdgeNode * first;
};
struct ALGraph
{
    VertexNode adjlist[100];
    int ver_num, edge_num;
};

ALGraph * CreateALGraph()
{
    ALGraph * g = new ALGraph;
    EdgeNode * edge;
    int i, j, k;
    cout << "请输入顶点数和边数" << endl;
    cin >> g->ver_num >> g->edge_num;
    cout << "请输入顶点信息" << endl;
    for (i = 0; i < g->ver_num; i++)
    {
        cin >> g->adjlist[i].Vertex;//输入顶点信息
        g->adjlist[i].first = NULL;
    }
    cout << "请输入边的信息" << endl;
    for (k = 0; k < g->edge_num; k++)
    {
        cin >> i >> j;//输入相连两节点的序号
        edge = new EdgeNode;
        edge->Adjv = j;
        EdgeNode * h;
        EdgeNode * t;
        //  cout<<g->adjlist[i].first<<endl;;
        if( g->adjlist[i].first == NULL )
        {

            g->adjlist[i].first = t = h = edge;
            h->next = NULL; 
        }
        else
        {
            while( t->next != NULL )
            {
                t = t->next;
            }
        //  cout<<t->Adjv<<endl;
            t->next = edge;
            edge->next = NULL;
        }
//          g->adjlist[i].first = edge;
    }
    return g;
}


void DFS( ALGraph * g , int i )//深度遍历算法
{
    EdgeNode * w;
    cout<<" 已访问的节点:"<<g->adjlist[i].Vertex<<endl;
    Visited[i] = 1;
    for( w = g->adjlist[i].first ; w ; w = w->next )
        if( !Visited[ w->Adjv ] )
            DFS( g , w->Adjv );
 } 


int main()
{
    ALGraph * g;
    g = CreateALGraph();
    for (int i = 0; i < g->ver_num; i++)
    {
        cout << g->adjlist[i].Vertex << " ";
        for (EdgeNode * p = g->adjlist[i].first; p != NULL; p = p->next)
        {
            cout << p->Adjv << " ";
        }
        cout << endl;
    }

    DFS(g,0);

    return 0;
}






b.临接矩阵的DFS
思路:我这里没有用递归,而是使用了栈,在临接矩阵中去遍历顶点I的临接节点j,若Edges[i][j]==1则把i入栈并且重新遍历,直到栈为空且J遍历完毕。

#include<iostream>
#include"stack.h" 
#define MAX 100;
#define MINFINITY 65535;
using namespace std;
typedef char VertexType;//顶点为char型
typedef int EdgeType;//边的权重为int型
int Visited[]={0};
struct MGraph {
    VertexType Vertices[100];//顶点表
    EdgeType Edges[100][100];//邻接矩阵
    int vertex_num; //顶点数
    int edge_num;   //边数
};

MGraph * CreateMGraph()
{

    MGraph *g = new MGraph;
    int i, j, k, w;

    cout << "请输入顶点数和边数(格式为:顶点数 边数)" << endl;
    cin >> g->vertex_num >> g->edge_num;
    cout << "请输入顶点信息" << endl;
    for (i = 0; i < g->vertex_num; i++)
    {
        cin >> g->Vertices[i];
    }
    for (i = 0; i < g->vertex_num; i++)
        for (j = 0; j < g->vertex_num; j++)
        {
            g->Edges[i][j] = 0;
        }
    cout << "输入每条边对应的两个顶点的序号和权值" << endl;
    for (k = 0; k < g->edge_num; k++)
    {
        cin >> i >> j >> w;
        g->Edges[i][j] = w;
      //  g->Edges[j][i] = w;
    }
    return g;

}

void DFS( MGraph * g , int  i )
{
    Stack<int> s;   
    cout<<"已访问的节点:"<<g->Vertices[i]<<endl;
    Visited[i]=1;
    int f=0;
    for( int j = 0 ; j < g->vertex_num  ; j++)
    {
        cout<<i<<":"<<j<<endl;
        if( g->Edges[i][j] == 1 && !Visited[j])
        {
            Visited[j]=1;
            s.Push(i);
            i=j;
            j=0;
            f=1; 
        }
        if( j == g->vertex_num-1 && !s.IsEmpty() )
        {
            i=s.Top();
            s.Pop();
            j=0;
        }

    }
}


int main()
{
    MGraph * g;
    g = CreateMGraph();
    for (int i = 0; i < g->vertex_num; i++)
    {
        for (int j = 0; j < g->vertex_num; j++)
        {
            cout << g->Edges[j][i] << " ";
        }
        cout << endl;
    }
    DFS(g,0);
    return 0;
}

2.BFS(广度优先遍历)
BFS:访问某节点N,然后遍历其临接并且未被访问的节点,让后从这些节点出发依次遍历,直到所有节点都被访问。
a.邻接矩阵的BFS

void BFS( MGraph * g , int n )
{
    Queue<int> q;
    cout<<"已访问节点:"<<g->Vertices[n]<<endl; 
    for( int j = 0 ; j < g->vertex_num ; j++ )
    {
        if( g->Edges[n][j] == 1 && !Visited[j])
        {
            cout<<"已访问节点:"<<g->Vertices[j]<<endl;
            q.Enqueue(j);
            Visited[j]=1; 
        }

    }
    while(!q.IsEmpty())
    {
        n = q.FrontAndDequeue();
        for( int j = 0 ; j < g->vertex_num ; j++ )
        {
            if( g->Edges[n][j] == 1 && !Visited[j])
            {
                cout<<"已访问节点:"<<g->Vertices[j]<<endl;
                q.Enqueue(j);
                Visited[j]=1; 
            }

        }
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值