您的位置:首页 > 其它

图的基本算法

2013-08-31 20:18 453 查看
1 图的表示

图的表示无外乎两种,邻接表表示法和邻接矩阵表示法。

对于上图,用邻接表表示如下:

1->2>5

2->1->3->4->5

3->2->4

4->2->5->3

5->1->2->4

而用邻接矩阵表示如下

   1    2   3     4    5

1    0    1   0     0    1

2    1    0   1     1     1

3   0    1     0     1    0

4   0    1     1     0     1

5   1    1    0      1    0

上面两种表示只是无向图的表示而已,图还分为有向图和无向图,表示方法都一样,无向图就好像是有向图中相连的顶点互相可达且路径长度为1.

在邻接矩阵中,矩阵内各元素定义为如果两个顶点i和j存在边,那么矩阵A中的元素aij=1,否则为0.

 

2.广度优先搜索

在给定图G=(V,E)和一个源点s的情况下,广度优先搜索系统的探索G中的边,以期发现可从s到达的所有顶点,并计算这些可达顶点之间的距离。该搜索算法可以生成一棵以源点s为根,且包含s的可达顶点的广度优先树。

  为了记录搜索的轨迹,广度优先搜索将每个顶点着色为白色,灰色和黑色。在搜索开始时,所有顶点都是白色的,随着搜索的进行各顶点逐渐变为灰色,然后变为黑色。搜索中第一次碰到某一个顶点时,称该顶点被发现了,此时该顶点变为非白色。因此,灰色和黑色顶点都是已经被发现的,但广度优先搜索还是对他们进行了区分,以确保搜索时以一种广度优先的方式进行的。

  广度优先搜索构造了一棵广度优先树,它在开始时只包含一个根顶点,即源顶点s。在某个已发现的顶点u的邻接表的过程中,每当发现一个白色顶点v,该顶点v即便(u,v)就被添加到树中。

下面的广度优先搜索过程BFS假定输入图G=(V,E)采用邻接表表示,对于图中的每个顶点,还采用了几种另外的数据结构,对每个顶点u属于V,其色彩存储在变量color[u]中,u的父母存在变量p[u]中。如果u没有父母,那么p[u]=NIL,由该算法算出的源顶点s和顶点u的距离存在变量d[u]中,该算法还采用了先进先出队列Q。

  下面是BFS过程

BFS

For each vertex u belong V[G]-{s};

    Do color[u]=WHITE;

       D[u]=inf

       P[u]=NIL

Color[s]=GRAY

D[s]=0

P[s]=NIL

Q=NULL

While Q!=NULL

    Do u=DEQUEUE(Q)

       For each vadj(u)

           Do ifcolor[u]==WHITE

              Thencolor[v]=GRAY

                    D[v]=d[u]+1

                    P[v]=u

                    Enqueue(Q,v)

       Color[u]=BLACK;

 

下面是打印源点s到某一顶点v的路径

PRINT_PATH(G,s,v)

If v==s

    Then print s

    Else if p[v]=NIL

       Then print “nopath from s to v”

       ElsePRINT_PATH(G,s,p[v])

           Print v

下面是我的源代码:

#include <list>

#include <queue>

#include <iostream>

#include <fstream>

using namespace std;

 

int dis[5];

int color[5];

int p[5];

void dfs(list<int> *arr,int s)

{

    queue<int>q;

    q.push(s);

    p[s]=0;

    dis[s]=0;

    color[s]=2;

    int u;

    list<int>::iteratorpos;

    while(!q.empty())

    {

       u=q.front();

       q.pop();

       pos=arr[u].begin();

       while(pos!=arr[u].end())

       {

           if(color[*pos-1]==1)

           {

              if(dis[*pos-1]>dis[u]+1)

              {

                  p[*pos-1]=u;

                  dis[*pos-1]=dis[u]+1;

                  color[*pos-1]=2;

                 

              }

              q.push(*pos-1);

           }

           ++pos;

          

       }

       color[u]=0;

    }

    for(inti=0;i<5;i++)

    {

       cout<<dis[i]<<'';

    }

    cout<<endl;

}

 

int main()

{

    ifstreamcin("a.txt");

    int n,i,j,from,to;

    cin>>n;

    list<int>*arr=new list<int>
;

    list<int>::iteratorpos;

    for(i=0;i<n;i++)

    {

       dis[i]=10000;

       color[i]=1;

       p[i]=-1;

    }

    while(cin>>from>>to&& from!=to)

    {

       arr[from-1].push_back(to);

    }

    cout<<"--------------"<<endl;

    for(i=0;i<n;i++)

    {

       pos=arr[i].begin();

       while(pos!=arr[i].end())

       {

           cout<<*pos<<'';

           ++pos;

       }

       cout<<endl;

    }

    cout<<"--------------"<<endl;

    dfs(arr,0);

    return 0;

}

这个算法只能用于上面的无向图,对于其图相应的改一下数组的长度以及循环中的次数即可

 

3.深度优先搜索

正如深度优先搜索这一名称一样,这种搜索算法是尽可能“深”的搜索一个图。

废话不多说,直接上伪代码

DFS(G)

For each vertex u belong V[G]

Do color[u]=WHITE

   P[u]=NIL

Time=0

For each vertex u belong V[G]

    Do ifcolor[u]=WHITE

       ThenDFS_VISIT(u)

 

DFS_VISIT(u)

Color[u]=GRAY

Time=time+1;

D[u]=time

For each v adj(u)

    Do ifcolor[v]==WHITE

           P[v]=u

           DFS_VISIT(v)

Color[u]=BLACK

F[u]=time=time+1

上面的深度优先搜索伪代码中,在搜索的同时为每个顶点加上时间戳,每个顶v有两个时间戳,当顶点v第一次被发现时,记录下第一个时间戳d[v],当结束检查v的邻接表时,记录下第二个时间戳f[v].

 

源代码:

#define BLACK 0

#define WHITE 1

#define GRAY 2

 

int n=10;

int color[10],d[10],f[10],p[10];

int time;

 

void Dfs(list<int>*arr,int u)

{

    color[u]=GRAY;

    time=time+1;

    d[u]=time;

    list<int>::iteratorpos=arr[u].begin();

    for(;pos!=arr[u].end();++pos)

    {

       if(WHITE==color[*pos-1])

       {

           p[*pos-1]=u;

           Dfs(arr,*pos-1);

       }

    }

    color[u]=BLACK;

    f[u]=time=time+1;

}

 

void dfs(list<int> *arr)

{

    int i;

    time=0;

    for(i=0;i<n;i++)

    {

       color[i]=WHITE;

       p
=-1;

    }

    for(i=0;i<n;i++)

    {

       if(color[i]==WHITE)

           Dfs(arr,i);

    }

}

4000
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息