图的遍历(DFS和BFS)

声明:图片及内容基于https://www.bilibili.com/video/BV1rp4y1Q72r?from=articleDetail

 图的遍历

深度优先遍历(DFS)

DFS核心是递归和栈

原理

邻接矩阵DFS代码

template <class T>
void MGraph<T>::DFS(int i){
    cout<<vertex[i]<<" ";
    visit[i]=1;
    for(int j=0;j<vertexNum;j++){      //对邻接矩阵的第i行的每一列遍历
        if(visit[j]==0&&arc[i][j]!=0&&arc[i][j]!=INFINIT){
            DFS(j);
        }
    }
}
template <class T>
void MGraph<T>::DFSTraverse(){
    for(int i=0;i<vertexNum;i++){   //visit数组初始化
        visit[i]=0;
    }
    for(int i=0;i<vertexNum;i++){   
        if(!visit[i])
            DFS(i);
    }
}

完整代码

#include<iostream>
#define MAXVAX 100
using namespace std;
const int INFINIT=65535;
int visit[MAXVAX];
template <class T>
class MGraph {
    private:
        T *vertex;         //顶点信息
        int **arc;         //邻接矩阵
        int vertexNum,arcNum;        //顶点数,边数
    public:
        MGraph(T v[],int n,int e);
        ~MGraph();
        void DFS(int i);
        void DFSTraverse();
        void display();
};
template <class T>
void MGraph<T>::DFS(int i){
    cout<<vertex[i]<<" ";
    visit[i]=1;
    for(int j=0;j<vertexNum;j++){
        if(visit[j]==0&&arc[i][j]!=0&&arc[i][j]!=INFINIT){
            DFS(j);
        }
    }
}

template <class T>
void MGraph<T>::DFSTraverse(){
    for(int i=0;i<vertexNum;i++){
        visit[i]=0;
    }
    for(int i=0;i<vertexNum;i++){
        if(!visit[i])
            DFS(i);
    }
}
template <class T>
MGraph<T>::MGraph(T v[],int n,int e) {  //n是顶点数,e是边数
    vertexNum=n;
    arcNum=e;
    vertex = new T[vertexNum];         //建立顶点信息
    arc = new int*[vertexNum];         //建立邻接表
    for(int i=0; i<vertexNum; i++)
        arc[i]=new int[vertexNum];

    for(int i=0; i<vertexNum; i++) {   //初始化顶点信息 
        vertex[i]=v[i];
    }
    for(int i=0;i<vertexNum;i++)       //初始化邻接表 
        for(int j=0;j<vertexNum;j++){
            if(i==j)     arc[i][j]=0;
            else     arc[i][j]=INFINIT;
        }
            
    int vi,vj,w;
    for(int i=0;i<arcNum;i++){
        cout<<"请输入边的两个顶点和这条边的权值"<<endl; 
        cin>>vi>>vj>>w;   //输入边依附的两个顶点的编号 和权值 
        arc[vi][vj]=w; //有边标志 
    }
}

template <class T>
void MGraph<T>::display(){
    for(int i=0;i<vertexNum;i++){
        for(int j=0;j<vertexNum;j++){
            cout<<arc[i][j]<<"\t";
        }
        cout<<endl;
    }
    cout<<endl;

    for(int i=0;i<vertexNum;i++){
        cout<<vertex[i]<<" ";
    }
    cout<<endl;
}

template <class T>
MGraph<T>::~MGraph(){
    delete []vertex;
    for(int i=0;i<vertexNum;i++)
        delete [] arc[i];
    delete [] arc;
}
int main(){
    const char* v[5]={"v0","v1","v2","v3","v4"};
    MGraph<const char*> mgraph(v,5,6);
    mgraph.display();
    mgraph.DFSTraverse();
    return 0;
}

 

邻接表DFS代码

void ALGraph::DFS(int v){

    visited[v]=1;
    cout<<adjList[v].vertex<<" ";
    ArcNode *p=adjList[v].firstEdge;
    while(p){
        if(!visited[p->adjvex])
            DFS(p->adjvex);
        p=p->next;
    }
}
void ALGraph::DFSTraverse(){
    int i;
    for(i=0;i<vertexNum;i++){
        visited[i]=0;
    }
    for(i=0;i<vertexNum;i++){
        if(!visited[i]){
            DFS(i);
        }
    }
}

完整代码

#include<iostream>
#include<string.h>
using namespace std;
const int MAX=10;
int visited[4]={0,0,0,0};
typedef struct ArcNode{     //边结点 
    int adjvex;
    ArcNode *next;
}ArcNode;
typedef struct {  //表头 
    int vertex;
    ArcNode *firstEdge;
}VertexNode[MAX];
class ALGraph{
    private:
        int vertexNum;
        int arcNum;
        VertexNode adjList;
    public:
        ALGraph(int v[],int n,int e);
        void display();
        void DFS(int v);
        void DFSTraverse();
};
void ALGraph::DFSTraverse(){
    int i;
    for(i=0;i<vertexNum;i++){
        visited[i]=0;
    }
    for(i=0;i<vertexNum;i++){
        if(!visited[i]){
            DFS(i);
        }
    }
}
void ALGraph::DFS(int v){

    visited[v]=1;
    cout<<adjList[v].vertex<<" ";
    ArcNode *p=adjList[v].firstEdge;
    while(p){
        if(!visited[p->adjvex])
            DFS(p->adjvex);
        p=p->next;
    }
}
ALGraph::ALGraph(int v[],int n,int e){
    vertexNum=n;
    arcNum=e;
    for(int i=0;i<vertexNum;i++){
        adjList[i].vertex=v[i];
        adjList[i].firstEdge=NULL;
    }
    int vi,vj;
    ArcNode *s;
    for(int i=0;i<arcNum;i++){
        cout<<"请输入第"<<i+1<<"条边的两个顶点在数组中的坐标"<<endl;
        cin>>vi>>vj;
        s=new ArcNode;
        s->adjvex=vj;
        s->next=adjList[vi].firstEdge;
        adjList[vi].firstEdge=s;
        s=new ArcNode;
        s->adjvex=vi;
        s->next=adjList[vj].firstEdge;
        adjList[vj].firstEdge=s;
    }
}
void ALGraph::display(){
    for(int i=0;i<vertexNum;i++){ 
        ArcNode *p=adjList[i].firstEdge;
        cout<<adjList[i].vertex;
        if(p) cout<<"->";
        while(p){
            cout<<p->adjvex<<" ";
            p=p->next;
            if(p) cout<<"->";
        } 
        cout<<endl;
    } 
}
int main(){
    int v[4]={0,1,2,3};
    ALGraph algraph(v,4,4);
    algraph.display();
    algraph.DFSTraverse();
    return 0;
}

 广度优先遍历(BFS)

BFS核心是队列

原理

 

邻接矩阵BFS代码

template <class T>
void MGraph<T>::BFS(int i) {
    queue<int> q;
    visit[i]=1;
    q.push(i);
    while(!q.empty()) {
        int t=q.front();
        cout<<vertex[t]<<" ";
        q.pop();
        for(int j=0; j<vertexNum; j++) {
            if(!vertex[i]&&arc[i][j]!=0&&arc[i][j]!=INFINIT) {
                visit[j]=1;
                q.push(j);
            }
        }
    }
}
template <class T>
void MGraph<T>::BFSTraverse() {
    for(int i=0; i<vertexNum; i++) { //visit数组初始化
        visit[i]=0;
    }
    for(int i=0; i<vertexNum; i++) {  //BFS
        if(!visit[i])
            BFS(i);
    }
}

完整代码

#include<iostream>
#include<queue>
#define MAXVAX 100
using namespace std;
const int INFINIT=65535;
int visit[MAXVAX];
template <class T>
class MGraph {
    private:
        T *vertex;         //顶点信息
        int **arc;         //邻接矩阵
        int vertexNum,arcNum;        //顶点数,边数
    public:
        MGraph(T v[],int n,int e);
        ~MGraph();void display();
        void BFS(int i);
        void BFSTraverse();
};

template <class T>
void MGraph<T>::BFS(int i) {
    queue<int> q;
    visit[i]=1;
    q.push(i);
    while(!q.empty()) {
        int t=q.front();
        cout<<vertex[t]<<" ";
        q.pop();
        for(int j=0; j<vertexNum; j++) {
            if(!vertex[i]&&arc[i][j]!=0&&arc[i][j]!=INFINIT) {
                visit[j]=1;
                q.push(j);
            }
        }
    }
}

template <class T>
void MGraph<T>::BFSTraverse() {
    for(int i=0; i<vertexNum; i++) { //visit数组初始化
        visit[i]=0;
    }
    for(int i=0; i<vertexNum; i++) {
        if(!visit[i])
            BFS(i);
    }
}

template <class T> MGraph<T>::MGraph(T v[],int n,int e) { //n是顶点数,e是边数 vertexNum=n; arcNum=e; vertex = new T[vertexNum]; //建立顶点信息 arc = new int*[vertexNum]; //建立邻接表 for(int i=0; i<vertexNum; i++) arc[i]=new int[vertexNum]; for(int i=0; i<vertexNum; i++) { //初始化顶点信息 vertex[i]=v[i]; } for(int i=0; i<vertexNum; i++) //初始化邻接表 for(int j=0; j<vertexNum; j++) { if(i==j) arc[i][j]=0; else arc[i][j]=INFINIT; } int vi,vj,w; for(int i=0; i<arcNum; i++) { cout<<"请输入边的两个顶点和这条边的权值"<<endl; cin>>vi>>vj>>w; //输入边依附的两个顶点的编号 和权值 arc[vi][vj]=w; //有边标志 } } template <class T> void MGraph<T>::display() { for(int i=0; i<vertexNum; i++) { for(int j=0; j<vertexNum; j++) { cout<<arc[i][j]<<"\t"; } cout<<endl; } cout<<endl; for(int i=0; i<vertexNum; i++) { cout<<vertex[i]<<" "; } cout<<endl; } template <class T> MGraph<T>::~MGraph() { delete []vertex; for(int i=0; i<vertexNum; i++) delete [] arc[i]; delete [] arc; } int main() { const char* v[5]= {"v0","v1","v2","v3","v4"}; MGraph<const char*> mgraph(v,5,6); mgraph.display(); mgraph.BFSTraverse(); return 0; }

邻接表BFS代码

void ALGraph::BFS(int i){
    queue<int> q;
    visited[i]=1;
    q.push(i);

    while(!q.empty()){
        int t=q.front();
        cout<<adjList[t].vertex<<" ";
        q.pop();
        ArcNode *p=adjList[i].firstEdge;
        while(p){                        
            if(!visited[p->adjvex]){
                q.push(p->adjvex);
                visited[p->adjvex]=1;
            }
            p=p->next;
        }
    }
}
void ALGraph::BFSTraverse(){
    int i;
    for(i=0;i<vertexNum;i++){
        visited[i]=0;
    }
    for(i=0;i<vertexNum;i++){
        if(!visited[i]){
            BFS(i);
        }
    }
}

完整代码

#include<iostream>
#include<string.h>
#include<queue>
using namespace std;
const int MAX=10;
int visited[4]={0,0,0,0};
typedef struct ArcNode{     //边结点 
    int adjvex;
    ArcNode *next;
}ArcNode;
typedef struct {  //表头 
    int vertex;
    ArcNode *firstEdge;
}VertexNode[MAX];
class ALGraph{
    private:
        int vertexNum;
        int arcNum;
        VertexNode adjList;
    public:
        ALGraph(int v[],int n,int e);
        void display();void BFS(int v);
        void BFSTraverse();
};
void ALGraph::BFS(int i){
    queue<int> q;
    visited[i]=1;
    q.push(i);

    while(!q.empty()){
        int t=q.front();
        cout<<adjList[t].vertex<<" ";
        q.pop();
        ArcNode *p=adjList[i].firstEdge;
        while(p){
            if(!visited[p->adjvex]){
                q.push(p->adjvex);
                visited[p->adjvex]=1;
            }
            p=p->next;
        }
    }
}
void ALGraph::BFSTraverse(){
    int i;
    for(i=0;i<vertexNum;i++){
        visited[i]=0;
    }
    for(i=0;i<vertexNum;i++){
        if(!visited[i]){
            BFS(i);
        }
    }
}

ALGraph::ALGraph(int v[],int n,int e){
    vertexNum=n;
    arcNum=e;
    for(int i=0;i<vertexNum;i++){
        adjList[i].vertex=v[i];
        adjList[i].firstEdge=NULL;
    }
    int vi,vj;
    ArcNode *s;
    for(int i=0;i<arcNum;i++){
        cout<<"请输入第"<<i+1<<"条边的两个顶点在数组中的坐标"<<endl;
        cin>>vi>>vj;
        s=new ArcNode;
        s->adjvex=vj;
        s->next=adjList[vi].firstEdge;
        adjList[vi].firstEdge=s;
        s=new ArcNode;
        s->adjvex=vi;
        s->next=adjList[vj].firstEdge;
        adjList[vj].firstEdge=s;
    }
}
void ALGraph::display(){
    for(int i=0;i<vertexNum;i++){ 
        ArcNode *p=adjList[i].firstEdge;
        cout<<adjList[i].vertex;
        if(p) cout<<"->";
        while(p){
            cout<<p->adjvex<<" ";
            p=p->next;
            if(p) cout<<"->";
        } 
        cout<<endl;
    } 
}
int main(){
    int v[4]={0,1,2,3};
    ALGraph algraph(v,4,4);
    algraph.display();
    algraph.BFSTraverse();
    return 0;
}

 

posted @ 2021-03-27 14:04  gonghr  阅读(347)  评论(0编辑  收藏  举报