数据结构——图的深度优先搜索算法(DFS)

这篇专栏记录的是图的深度优先搜索算法(DFS)。(完整代码在最下面)

对应的广度优先搜索算法

存储图,首先要定义顶点的结构体。

//边
typedef struct Edge{
    int adj;	//邻接点对应的的下标 
    Edge *next;	//指向下一个结点 
}Edge;
 
//顶点
typedef struct{
    int data;	//顶点信息 
    Edge *first;	//指向第一个邻接点 
}Node;

//图
typedef struct{
    Node Node[15];	//顶点 
    int numVertex, numEdge;	//顶点数,边数 
}Graph;

由于访问节点不能重复,因此要定义一个数组来标记该顶点是否已经访问。

bool DFSvisited[50];  //标记结点是否被访问过 

创建的图和存储图对应的邻接表如图所示。
在这里插入图片描述

图和存储图对应的邻接表

在这里插入图片描述

输出结果

执行顺序:
1、先访问Node[0].data(即1)。
2、由于Node[0].first.adj为1,所以访问Node[1].data(即2)。
3、由于Node[1].first.adj为4,所以访问Node[4].data(即5)。
4、由于Node[4].first为NULL,回退到Node[1].first。
5、由于Node[1].first.next为NULL,回退到Node[0].first。
6、由于Node[0].first.next.adj为2,所以访问Node[2].data(即3)。
7、由于Node[2].first为NULL,回退到Node[1].first.next。
8、由于Node[1].first.next.next.adj为3,所以访问Node[3].data(即4)。
9、由于Node[3].first已经访问过,回退,发现每一个顶点都访问过了。

完整代码:

#include <iostream>
using namespace std;
	
bool DFSvisited[50];  //标记结点是否被访问过 

//边
typedef struct Edge{
    int adj;	//邻接点对应的的下标 
    Edge *next;	//指向下一个结点 
}Edge;
 
//顶点
typedef struct{
    int data;	//顶点信息 
    Edge *first;	//指向第一个邻接点 
}Node;

//图
typedef struct{
    Node Node[15];	//顶点 
    int numVertex, numEdge;	//顶点数,边数 
}Graph;

//遍历,直到找到该顶点在图中的存储位置(即下标) 
int local(Graph G, int val){
    for(int i=0; i<G.numVertex; i++){
        if(G.Node[i].data == val)
            return i;	//返回该顶点在图中的存储位置
    }
    return -1;
}

void CreateGraph(Graph &G){	//创建图,用邻接表存储 
    cout << "请输入顶点数和边数:";
    cin  >> G.numVertex >> G.numEdge;
    for(int i=0; i<G.numVertex; i++){
		G.Node[i].data = i+1;	//结点信息初始化,也可以自己输入
		G.Node[i].first = NULL;
	}
	
	int v1, v2;
	cout << "请输入每条边的起点和终点:" << endl;
    for(int k=0; k<G.numEdge; k++){
        cin >> v1 >> v2;	//输入起点和终点的顶点信息 
        int src = local(G, v1);	
        int des = local(G, v2);
        if(G.Node[src].first == NULL){	//该结点的第一个邻接结点为空时 
            Edge *e = new Edge;
            e->adj = des;
            e->next = NULL;
            G.Node[src].first = e;	//给第一个邻接结点赋值 
        }
        else{	//该结点的第一个邻接结点不为空时
            Edge *p = G.Node[src].first;
            while(p->next != NULL){
                p = p->next;	//先循环到最后一个邻接节点处 
            }
            Edge *e = new Edge;
            e->adj = des;
            e->next = NULL;
            p->next = e;	//再在最后添加一个新的邻接节点 
        }
    }
}

void Print(Graph G){	//按下标输出各个顶点信息 
    cout<<"所建立的邻接表如以下所示:"<<endl;
    for(int i=0; i<G.numVertex; i++){
        cout << "[" << i << "]" << ")";	//先输出顶点信息
        Edge *e = G.Node[i].first;
        while(e){	//然后就开始遍历输出每个结点的信息 
            cout << "-->" << "[" << e->adj << "]";
            e = e->next;
        }
        cout << endl;
    }
}

void DFS(Graph G, int i){
    DFSvisited[i] = true;	//标记为已访问 
    cout << G.Node[i].data << " ";	//输出该顶点信息 
    Edge *p = G.Node[i].first;
    while(p){
        if(!DFSvisited[p->adj])	//若顶点未访问 
            DFS(G, p->adj);		//递归调用 
        p = p->next;
    }
}

void DFSTraverse(Graph G){	//深度搜索 
    for(int i=0; i<G.numVertex; i++)
        DFSvisited[i] = false;	//标记为未访问 
    cout << endl << "深度遍历:";
    for(int i=0; i<G.numVertex; i++){
        if(!DFSvisited[i])	//如果未访问 
            DFS(G, i);
    }
}

int main(){
	Graph G;
	CreateGraph(G);
	DFSTraverse(G);
	return 0;
}


氷鸢鸢鸢
2020.2.13

发布了19 篇原创文章 · 获赞 21 · 访问量 4536

猜你喜欢

转载自blog.csdn.net/koori_145/article/details/104296213