[数据结构复习]图

来源:互联网 发布:d3.js圆形动态加载 编辑:程序博客网 时间:2024/04/30 16:55

1.图的表示

1)邻接矩阵

   对于普通图,0 /1

    对于网络(或带权图),邻接矩阵的值  0/N

2)邻接表

    如果点多边少,用邻接矩阵很浪费存储空间,这时候用邻接表。

   用邻接表的话,如果想得到顶点的入度,必须检测其他所有顶点对应的边链表,这时候可以建立逆邻接表。

 

3.邻接多重表

邻接多重表在要求每条边处理一次的实际应用中特别有用。


2.图的遍历

1)深度优先遍历(DFS)

给每个点一个位记录是否已经访问;要使用递归。

算法代码:

//从顶点位置v出发

void DFS(Graph G,int v,bool visited[]){

visited[v]=true;

int w=G.getFirstNeighbor(v);

while(w!=-1){

       if(visited[w]==false) 

                 DFS(G,w,visited);

       w=G.getNextNeighbor(v,w);

}

};

      

     

2)广度优先遍历(BFS)

给每个点一个位记录是否已经访问;要用到一个队列;不递归。

void BFS(Graph G){

     Queue q;

     Q.enqueue(v);

     while(!q.empty()){

          int v=q.dequeue();

          int d=G.getFirstNeighbor(v);

          while(d!=-1){

                if(visited(d)==false)

                      visited(d)=true;

                      q.enqueue(d);

                d=G.getNextNeighbor(v);

           }

    }

}


3.最小生成树

1)Kruskal算法

     每次选出一条具有最小权值,且两端点不在同一连通分量上的边,加入生成树。

2)Prim算法

    每次选出一个端点在生成树中,另一个端点不在生成树中的权值最小的边加入生成树中。


4.最短路径

1)非负权值的单元最短路径_Dijkstra算法

(以下转自http://www.cnblogs.com/biyeymyhjob/archive/2012/07/31/2615833.html)

const int  MAXINT = 32767;const int MAXNUM = 10;int dist[MAXNUM];int prev[MAXNUM];int A[MAXNUM][MAXNUM];void Dijkstra(int v0){    bool S[MAXNUM];                                  // 判断是否已存入该点到S集合中      int n=MAXNUM;    for(int i=1; i<=n; ++i)    {        dist[i] = A[v0][i];        S[i] = false;                                // 初始都未用过该点        if(dist[i] == MAXINT)                  prev[i] = -1;        else               prev[i] = v0;     }     dist[v0] = 0;     S[v0] = true;       for(int i=2; i<=n; i++)    {         int mindist = MAXINT;         int u = v0;                               // 找出当前未使用的点j的dist[j]最小值         for(int j=1; j<=n; ++j)            if((!S[j]) && dist[j]<mindist)            {                  u = j;                             // u保存当前邻接点中距离最小的点的号码                   mindist = dist[j];            }         S[u] = true;          for(int j=1; j<=n; j++)             if((!S[j]) && A[u][j]<MAXINT)             {                 if(dist[u] + A[u][j] < dist[j])     //在通过新加入的u点路径找到离v0点更短的路径                   {                     dist[j] = dist[u] + A[u][j];    //更新dist                      prev[j] = u;                    //记录前驱顶点                   }              }     }}

算法实例

先给出一个无向图

用Dijkstra算法找出以A为起点的单源最短路径步骤如下



2)任意权值的单源最短路径_Bellman-Ford算法

主要是两点:

1.此路径最多有n-1条边

2.递推式 



3)所有顶点之间的最短路径_Floyd算法

typedef struct          {            char vertex[VertexNum];                                //顶点表             int edges[VertexNum][VertexNum];                       //邻接矩阵,可看做边表             int n,e;                                               //图中当前的顶点数和边数         }MGraph; void Floyd(MGraph g){   int A[MAXV][MAXV];   int path[MAXV][MAXV];   int i,j,k,n=g.n;   for(i=0;i<n;i++)      for(j=0;j<n;j++)      {                A[i][j]=g.edges[i][j];            path[i][j]=-1;       }   for(k=0;k<n;k++)   {         for(i=0;i<n;i++)           for(j=0;j<n;j++)               if(A[i][j]>(A[i][k]+A[k][j]))               {                     A[i][j]=A[i][k]+A[k][j];                     path[i][j]=k;                }      } }


5.AOV网络(activity on vertice)

拓扑排序:

每次选出入度为0的顶点,然后去掉这个顶点以及它的发出边。




0 0
原创粉丝点击