基本概念
     完全图:图中有n个结点,n(n-1 )/2条边的无向图。
    有向完全图:图中有n个结点,n(n-1 )条弧的有向图。
    稀疏图:假设图中有n个结点e条边,若边的个数 e < nlogn, 则称为稀疏图。
    简单路径:顶点不重复的路径称为简单路径。
    回路:首尾顶点相同的路径称为回路。
    连通图:任意两个结点间都有路径连通。
    强连通图:在有向图中, 任意两个顶点之间存在一条有向路径。
    生成树:包含连通图中的全部顶点的极小连通子图称为该图的生成树,假设一个连通图有n个顶点,其中n个顶点和n-1条边构成一个极小的连通图。

邻接矩阵:可以表示图中顶点之间的相邻关系。对于具有n个顶点的无向图,只需n(n-1)/2个空间。矩阵对称。对于有向图,邻接矩阵不一定对称,所以需要n^2个空间。


linjie


邻接表:用于解决稀疏图时使用邻接矩阵造成的空间浪费问题,逆邻接矩阵的结构与邻接表完全相同,只是边表中每个结点存放的是该顶点通过入度弧所邻接的所有顶点。

linjiebiao


十字链表:有向图的另一种链式存储结构,可以看成邻接表和逆邻接表的结合。
数据类型描述:
typedef struct ArcNode
{
  int tailvex, headvex;   //起点终点的顶点序号
  int weight;      
  struct ArcNode *hnextarc, *tnextarc;   //指向具有同一起点或者终点的下一条弧
}ArcNode;

typedef struct VertexNode
{
   char  vexdata;
   ArcNode *head, *tail;
}VertexNode;

typedef struct
{
   VertexNode vertex[MAXVEX]; 
   int vexnum;      //顶点数
   int arcnum;   //弧数
}OrthList;

多重链表:适用于无向图的链式存储方式,在多重链表中存放的是真正的边。

递归深度优先搜索遍历连通子图
int visited[MAXVEX ] = {0 };
void DFS (Graph g, int v0 )
{
    visit(v0 );
    visited[v0] = 1 ;
    w = FirstAdjVex(g, v0 );
    while (w != -1 ) {
        if ( !visited[w] )     DFS(g, w );
         w = NexAdjVex(g, v0, w );
     }
}
非递归深度优先搜索遍历连通子图
void DFS (Graph g, int v0 )
{
    InitStack(S );
    int visited[MAXEX ] = {0 };
    Push(S, v0 );
    while ( ! Empty(S ) ) {
         v= Pop(S );
         if ( !visited[v ] ) {
            visit(v );
              visited[v ] = 1;
          }
         w = FirstAdjVertex(g, v ) ;  //图g中顶点v的第一个邻接点
         whil e ( w != -1 ) {
            if ( !visit[w])   Push(S, w );
              w = NextAdjVertex(g, v, w );     //图g中顶点v的下一个邻接点
          }
     }
}
对于具有n个顶点e条边的无向图或有向图,用邻接矩阵存储,时间复杂度O(n^2)。用邻接表存储,时间复杂度为O(e)。对应的深度优先搜索遍历算法的时间复杂度为O(n+e)。

广度优先搜索遍历连通子图
void BFS (Graph g, int v0 )
{
    visit(v0 );
    visited[0 ] = 1;
    InitQueue(Q );
    EnterQueue(&Q, v0 );
    while ( !Empty(Q ) ) {
        DeleteQueue(&Q, &v );
         w = FirstAdj(g , v );
         while ( w != -1 ) {
            if ( !visited[w]) {
                   visit(w );
                   visited[w] = 1;
                   EnterQueue(&Q, w );
               }
              w = NextAdj(g, v, w );
          }
     }   
}
若在遍历过程中不止一次的调用搜索过程,则说明该图是一个非连通图,而且调用几次遍历过程,说明该图有几个连通分量。判断图中是否有回路,DFS可以,BFS不行。

图的应用
概念
     图G的生成树是指该图的一个极小的连通子图,含有图中的全部n个顶点,但只有足以构成一棵树的n-1条边。生成树不唯一,n-1条边权值之和最小的生成树就是最小代价生成树。

1.Prim算法
    加点法。从连通图某一顶点v0出发,选择与它关联的具有最小权值的边将其顶点加入到生成树的集合U 中。
2.Kruskal算法(主要由边的排序、判断以及合并连通分量实现)
    加边法。先构造一个只含n个顶点的子图SG,然后从权值最小的开始,若他的添加不使SG产生回路,则在SG中加入该边。(将边的权值从小到大 排序, 依次加入 )时间复杂度O(elog2 (e ) )。

拓扑排序
    从有向图中选取一个没有前驱的顶点并输出。
    从有向图中删去该顶点以及所有以他为尾的弧。
    重复上述两步,直到图空。拓扑序列可以检查有向图中是否存在回路。





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值