图的深度优先搜索与广度优先搜索

DFS(深度优先搜索)和BFS(广度优先搜索)是两种最基本的搜索方法,不仅是在图论中在其他很多方面都有应用,也就是说,dfs和bfs是ACM的基础,要熟练掌握他们就要深刻理解它们的搜索原理。那么图的深搜和广搜也是图论的基础,许多知识点都会应用到搜索,比如拓扑排序,深搜和广搜的定义就不说了,下面是图的dfs和bfs搜索代码:

下面采用邻接表存储结构实现:

//图的深度优先搜索
//邻接表
#include 
#include 
#include 
#include 
#define Max 100 //顶点个数最多为100个
using namespace std;
typedef char type;
typedef struct Arcnode{
	int index;
	int value;
	struct Arcnode *next;
}Arcnode,*parc;
typedef struct Node{
	type data;
    Arcnode *first;
}Node;
typedef struct Grap{
	Node nodetex[Max];
	int n; //顶点数
	int m; //边数
}Grap,*pgrap;
bool visit[Max];
int Located(pgrap g,char ch){
	for(int i=0;in;i++)
		if(ch==g->nodetex[i].data)
			return i;
}
void Creat_grap(pgrap g){
	printf("输入图的结点数和边数:\n");
	scanf("%d%d",&g->n,&g->m);
	getchar();
	int i,index1,index2,value;
	char ch1,ch2;
	printf("输入各顶点:\n");
	for(i=0;in;i++){
	g->nodetex[i].data=getchar();
	g->nodetex[i].first=NULL;
	getchar();
	}
	printf("输入各边及权值:\n");	
	parc q;
	for(i=0;im;i++){
		scanf("%c,%c,%d",&ch1,&ch2,&value);
		getchar();
		index1=Located(g,ch1);
		index2=Located(g,ch2);
		q=(parc)malloc(sizeof(Arcnode));
		q->index=index2;
		q->value=value;
		q->next=g->nodetex[index1].first;
		g->nodetex[index1].first=q;
		//无向图(默认为任意两个顶点之间之多有一条边且自身到自身无边)
		q=(parc)malloc(sizeof(Arcnode));
		q->index=index1;
		q->value=value;
		q->next=g->nodetex[index2].first;
		g->nodetex[index2].first=q;
	}
}
void Delete_grap(pgrap g){
	parc p,q;
	for(int i=0;in;i++){
		p=g->nodetex[i].first;
		while(p){
			q=p->next;
			free(p);
			p=q;
		}
	}
}
//递归算法
/*void dfs(pgrap g,int v){
	printf("访问结点: ");
	putchar(g->nodetex[v].data);
	visit[v]=1;
	parc p=g->nodetex[v].first;
	while(p){
		if(!visit[p->index])
			dfs(g,p->index);
		p=p->next;
	}
}*/
//非递归算法
void dfs(pgrap g,int v){
	stack s;
	s.push(v);
	int index;
	while(!s.empty()){
		index=s.top();
		s.pop();
		if(visit[index])
			continue;
		printf("访问结点: ");
		putchar(g->nodetex[index].data);
		visit[index]=1;
		parc p=g->nodetex[index].first;
		while(p){
			if(!visit[p->index])
				s.push(p->index);
			p=p->next;
		}
	}
}
void Pdfs(pgrap g){
	memset(visit,0,sizeof(visit));
	for(int i=0;in;i++)
		if(!visit[i])
			dfs(g,i);
}

int main(){
	Grap g;
	pgrap p=&g;
	Creat_grap(p);
	Pdfs(p);
	Delete_grap(p);
	return 0;
}	
			
测试数据:

输入图的结点数和边数:
5 7
输入各顶点:
A
B
C
D
E
输入各边及权值:
A,B,20
A,C,10
B,D,50
A,D,40
B,E,60
C,D,30
D,E,70
访问结点: A访问结点: D访问结点: E访问结点: B访问结点: C


Terminated with return code 0
Press any key to continue ...


输入图的结点数和边数:
8 9
输入各顶点:
A
B
C
D
E
F
G
H
输入各边及权值: //无向图
A,B,0
A,C,0
B,D,0
B,E,0
C,F,0
C,H,0
D,G,0
E,G,0
F,G,0
访问结点: A访问结点: C访问结点: H访问结点: F访问结点: G访问结点: E访问结点: B访
问结点: D


Terminated with return code 0
Press any key to continue ...


输入图的结点数和边数://有向图
8 9
输入各顶点:
A
B
C
D
E
F
G
H
输入各边及权值:
A,B,0
A,C,0
B,D,0
B,E,0
C,F,0
C,H,0
D,G,0
E,G,0
F,G,0
访问结点: A访问结点: C访问结点: H访问结点: F访问结点: G访问结点: B访问结点: E访
问结点: D


Terminated with return code 0
Press any key to continue ...

下面采用图的邻接矩阵实现:

//图的邻接矩阵表示法
#include 
#include 
#include 
#include 
using namespace std;
#define Max 100
#define Inf 0x1111
typedef char type;
typedef struct Grap{
	type data[Max];
	int value[Max][Max];
	int n,m;
}Grap,*pgrap;
int visit[Max];
int Located(pgrap g,char ch){
	for(int i=0;in;i++)
		if(g->data[i]==ch)
			return i;
}
void Creat_grap(pgrap g){
	printf("输入图的顶点数和边数:\n");
	scanf("%d%d",&g->n,&g->m);
	//printf("ksgfdkj\n");
	getchar();
	printf("输入图中的顶点:\n");
	int i,j;
	for(i=0;in;i++){
		g->data[i]=getchar();
		getchar();
	}
	for(i=0;in;i++)
		for(j=0;jn;j++)
			g->value[i][j]=Inf;
	printf("请输入图中的边:\n");
	int index1,index2,value;
	char ch1,ch2;
	while(g->m--){
		scanf("%c,%c,%d",&ch1,&ch2,&value);
	    getchar();
		index1=Located(g,ch1);
		index2=Located(g,ch2);
		g->value[index1][index2]=value;
		//无向图
		g->value[index2][index1]=value;
	}
}
/*void Show_grap(pgrap g){
	printf("邻接矩阵表示法个顶点的邻接顶点:\n");
	int i,j;
	for(i=0;in;i++){
		printf("%c:",g->data[i]);
		for(j=0;jn;j++)
			if(g->value[i][j]!=Inf)
				putchar(g->data[j]);
		printf("\n");
	}
}*/
//递归算法
/*void dfs(pgrap g,int v){
	printf("访问结点: ");
	putchar(g->data[v]);
	visit[v]=1;
	for(int i=0;in;i++)
		if(g->value[v][i]!=Inf && !visit[i])
			dfs(g,i);
}*/
//非递归算法
void dfs(pgrap g,int v){
	stack s;
	s.push(v);
	int index;
	while(!s.empty()){
		index=s.top();
		s.pop();
		if(visit[index])
			continue;
		printf("访问结点: ");
		putchar(g->data[index]);
		visit[index]=1;
		for(int i=0;in;i++)
			if(g->value[index][i]!=Inf && !visit[i])
				s.push(i);
	}
}
void Pdfs(pgrap g){
	memset(visit,0,sizeof(visit));
	for(int i=0;in;i++)
		if(!visit[i])
			dfs(g,i);
}
int main(){
	Grap g;
	pgrap p=&g;
	Creat_grap(p);
	//Show_grap(p);
	Pdfs(p);
	return 0;
}		

下面是测试数据:

输入图的结点数和边数: //无向图
8 9
输入各顶点:
A
B
C
D
E
F
G
H
输入各边及权值:
A,B,0
A,C,0
B,D,0
B,E,0
C,F,0
C,H,0
D,G,0
E,G,0
F,G,0
访问结点: A访问结点: B访问结点: D访问结点: G访问结点: E访问结点: F访问结点: C访
问结点: H


Terminated with return code 0
Press any key to continue ...


输入图的结点数和边数: //有向图
8 9
输入各顶点:
A
B
C
D
E
F
G
H
输入各边及权值:
A,B,0
A,C,0
B,D,0
B,E,0
C,F,0
C,H,0
D,G,0
E,G,0
F,G,0
访问结点: A访问结点: B访问结点: D访问结点: G访问结点: E访问结点: C访问结点: F访
问结点: H


Terminated with return code 0
Press any key to continue ...

下面是dfs代码:

采用邻接矩阵实现:

//图的邻接矩阵表示法

//图的邻接矩阵表示法
#include 
#include 
#include 
#include 
using namespace std;
#define Max 100
#define Inf 0x1111
typedef char type;
typedef struct Grap{
	type data[Max];
	int value[Max][Max];
	int n,m;
}Grap,*pgrap;
int visit[Max];
int Located(pgrap g,char ch){
	for(int i=0;in;i++)
		if(g->data[i]==ch)
			return i;
}
void Creat_grap(pgrap g){
	printf("输入图的顶点数和边数:\n");
	scanf("%d%d",&g->n,&g->m);
	//printf("ksgfdkj\n");
	getchar();
	printf("输入图中的顶点:\n");
	int i,j;
	for(i=0;in;i++){
		g->data[i]=getchar();
		getchar();
	}
	for(i=0;in;i++)
		for(j=0;jn;j++)
			g->value[i][j]=Inf;
	printf("请输入图中的边:\n");
	int index1,index2,value;
	char ch1,ch2;
	while(g->m--){
		scanf("%c,%c,%d",&ch1,&ch2,&value);
	    getchar();
		index1=Located(g,ch1);
		index2=Located(g,ch2);
		g->value[index1][index2]=value;
		//无向图
		g->value[index2][index1]=value;
	}
}
/*void Show_grap(pgrap g){
	printf("邻接矩阵表示法个顶点的邻接顶点:\n");
	int i,j;
	for(i=0;in;i++){
		printf("%c:",g->data[i]);
		for(j=0;jn;j++)
			if(g->value[i][j]!=Inf)
				putchar(g->data[j]);
		printf("\n");
	}
}*/
void bfs(pgrap g,int v){
	queue q;
    q.push(v);
	int index;
	while(!q.empty()){
		index=q.front();
		q.pop();
		if(visit[index])
			continue;
		printf("访问结点: ");
		putchar(g->data[index]);
		visit[index]=1;
		for(int i=0;in;i++)
			if(g->value[index][i]!=Inf && !visit[i])
				q.push(i);
	}
}
void Pbfs(pgrap g){
	memset(visit,0,sizeof(visit));
	for(int i=0;in;i++)
		if(!visit[i])
			bfs(g,i);
}
int main(){
	Grap g;
	pgrap p=&g;
	Creat_grap(p);
	//Show_grap(p);
	Pbfs(p);
	return 0;
}	
	

下面采用邻接表实现:

//图的存储结构
//邻接表
#include 
#include 
#include 
#include 
using namespace std;
#define Max 100 //顶点个数最多为100个
typedef char type;
typedef struct Arcnode{
	int index;
	int value;
	struct Arcnode *next;
}Arcnode,*parc;
typedef struct Node{
	type data;
    Arcnode *first;
}Node;
typedef struct Grap{
	Node nodetex[Max];
	int n; //顶点数
	int m; //边数
}Grap,*pgrap;
bool visit[Max];
int Located(pgrap g,char ch){
	for(int i=0;in;i++)
		if(ch==g->nodetex[i].data)
			return i;
}
void Creat_grap(pgrap g){
	printf("输入图的结点数和边数:\n");
	scanf("%d%d",&g->n,&g->m);
	getchar();
	int i,index1,index2,value;
	char ch1,ch2;
	printf("输入各顶点:\n");
	for(i=0;in;i++){
	g->nodetex[i].data=getchar();
	g->nodetex[i].first=NULL;
	getchar();
	}
	printf("输入各边及权值:\n");	
	parc q;
	for(i=0;im;i++){
		scanf("%c,%c,%d",&ch1,&ch2,&value);
		getchar();
		index1=Located(g,ch1);
		index2=Located(g,ch2);
		q=(parc)malloc(sizeof(Arcnode));
		q->index=index2;
		q->value=value;
		q->next=g->nodetex[index1].first;
		g->nodetex[index1].first=q;
		//无向图(默认为任意两个顶点之间之多有一条边且自身到自身无边)
		q=(parc)malloc(sizeof(Arcnode));
		q->index=index1;
		q->value=value;
		q->next=g->nodetex[index2].first;
		g->nodetex[index2].first=q;
	}
}
void bfs(pgrap g,int v){
	queue q;
    q.push(v);
	int index;
	while(!q.empty()){
		index=q.front();
		q.pop();
		if(visit[index])
			continue;
		printf("访问结点: ");
		putchar(g->nodetex[index].data);
		visit[index]=1;
		parc p=g->nodetex[index].first;
		while(p){
			if(!visit[p->index])
				q.push(p->index);
			p=p->next;
		}
	}
}
void Pbfs(pgrap g){
	memset(visit,0,sizeof(visit));
	for(int i=0;in;i++)
		if(!visit[i])
			bfs(g,i);
}
void Delete_grap(pgrap g){
	parc p,q;
	for(int i=0;in;i++){
		p=g->nodetex[i].first;
		while(p){
			q=p->next;
			free(p);
			p=q;
		}
	}
}
int main(){
	Grap g;
	pgrap p=&g;
	Creat_grap(p);
	Pbfs(p);
	Delete_grap(p);
	return 0;
}	




你可能感兴趣的:(acm,图的搜索)