图的遍历

来源:互联网 发布:淘宝店铺名搜索不到 编辑:程序博客网 时间:2024/05/19 00:37

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 0