广度优先遍历、深度优先遍历

图的遍历

1.什么是图的遍历

是指从图中的某个顶点出发,按照某种搜索方式沿着图中的边对图中的所有顶点访问依次,且仅访问一次

2.两种遍历算法

2.1广度优先搜索

基本思想:首先访问起始顶点v,接着由v出发,依次访问v的各个未访问过的邻接顶点w1,w2,……,wi,然后依次访问w1,w2,……,wi的所有未被访问过的邻接顶点,在从这些访问过的顶点出发,访问他们所有未被访问过的邻接顶点,直至图中所有的顶点都被访问过为止。

bool visited[MAX_VERTEX_NUM];//标记访问数组
void BFSTraverse(Graph G){//对图G进行广度优先遍历
    for(int i=0;i<=G.vexnum;i++){
        visited[i]=false;//访问标记数组初始化
    }
    InitQueue(Q);//初始化一个辅助队列Q
    for(int i=0;i<G.vexnum;i++){//从0号顶点开始遍历
        if(!visited[i]){//对每个连通分量调用一次BFS()
            BFS(G,i);//若vi未被访问过,从vi开始调用BFS()
        }
    }
}
2.1.1邻接表实现
void BFS(ALGraph G,int i){
    visit(i);//访问初始顶点i
    visited[i]=true;//对i做已访问标记
    EnQueue(Q,i);//i入队
    while(!IsEmpty(Q)){//队列不空
        DeQueue(Q,v);//队头元素出队
        for(p=G.vertics[v].firstarc;p;p=p->nextarc){//检测v的所有邻接点
            w=p-adjvex;
            if(visited[w]==false){//w为v未被访问的邻接点,访问w
                visit(w);
                visited[w]=true;
                EnQueue(Q,w);
            }
        }
    }
}
2.1.2邻接矩阵实现
void BFS(ALGraph G,int i){
    visit(i);//访问初始顶点i
    visited[i]=true;//对i做已访问标记
    EnQueue(Q,i);//i入队
    while(!IsEmpty(Q)){//队列不空
        DeQueue(Q,v);//队头元素出队
        for(w=0;w<G.vexnum;w++){//检测v的所有邻接点
            if(visited[w]==false&&G.edge[v[w]==1]){//w为v未被访问的邻接点,访问w
                visit(w);
                visited[w]=true;
                EnQueue(Q,w);
            }
        }
    }
}

辅助数组visited[]标志顶点是否被访问过,其初始态为FALSE,在图的遍历过程中,一旦某个顶点i被访问过,就立即置visited[i]=true,防止它多次被访问。

2.1.3性能分析

无论是邻接表还是邻接矩阵的存储方式,BFS都需要借助一个辅助队列Q,n个顶点都需要入队一次,最坏时,空间复杂度为O(|V|)。

时间复杂度:邻接表——O(|V|+|E|),邻接矩阵——O(|V|*|V|)

3.1深度优先搜索

算法思想:首先访问图中的某一个 顶点v,然后由v出发,访问与v邻接且未被访问过的任意一个顶点w1,再访问与w1邻接且未被访问过的任意一个顶点w2……重复上述过程。当不能再继续向下访问时,依次退回到最近且被访问过的顶点,若它还有邻接点未被访问过,则从该点开始继续上述过程,直至图中所有顶点均被访问过为止。

bool visited[MAX_VERTEX_NUM];//标记访问数组
void DFSTraverse(Graph G){//对图G进行深度优先遍历
    for(int i=0;i<=G.vexnum;i++){
        visited[i]=false;//访问标记数组初始化
    }
    for(int i=0;i<G.vexnum;i++){//从0号顶点开始遍历
        if(!visited[i]){//对每个连通分量调用一次DFS()
            DFS(G,i);//若vi未被访问过,从vi开始调用DFS()
        }
    }
}
3.1.1邻接表实现
void DFS(ALGraph G,int i){
    visit(i);//访问初始顶点i
    visited[i]=true;//对i做已访问标记
    for(p=G.vertics[v].firstarc;p;p=p->nextarc){//检测v的所有邻接点
            j=p-adjvex;
            if(visited[j]==false){//j为v未被访问的邻接点,访问j
                DFS(G,j);
            }
        }
    }
3.1.2邻接矩阵实现
void DFS(ALGraph G,int i){
    visit(i);//访问初始顶点i
    visited[i]=true;//对i做已访问标记
    for(j=0;j<G.vexnum;j++){//检测v的所有邻接点
            if(visited[j]==false&&G.edge[i][j]==1]){//j为j未被访问的邻接点,访问j
                DFS(G,j);
            }
        }
    }
3.1.3性能分析

DFS是一个递归算法,需要借助一个递归工作栈,所以空间复杂度为O(|V|)。

时间复杂度:邻接表——O(|V|+|E|),邻接矩阵——O(|V|*|V|)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值