深度优先搜索和广度优先搜索

以清华大学《计算机软件技术基础》习题2.34为例。

题目如下:

深度优先搜索的主要部分代码如下:

//用邻接表结构进行深度优先搜索
typedef int Boolean;  //定义布尔类型,用于标记点是否被访问
Boolean visited[MAXVEX];   //标记已访问的点
//算法
void DFS(GraphList *GL,int i)  //从下标为i的顶点开始搜索
{
	EdgeNode *p;
	visited[i] = true;
	cout<<GL->adjlist[i].data<<"  ";   //输出已访问的点
	p = GL->adjlist[i].firstedge;
	while(p)
	{
		if(!visited[p->adjvex])
			DFS(GL,p->adjvex);   //对未访问的顶点做递归调用
		p = p->next;
	}
}
//操作
void DFSTraverse(GraphList *GL)
{
	int i;
	//对所有顶点状态初始化
	for (i=0;i<GL->numV;i++)
		visited[i] = false;
	for(i=0;i<GL->numV;i++)
	{
		if(!visited[i])
			DFS(GL,i);
	}
}

广度优先搜索的主要部分代码如下:(其中用到的队的结构及算法见完整代码)

//广度优先搜索主体部分
void BFSTraverse(GraphList *GL)
{
	typedef int Boolean;  //定义布尔类型,用于标记点是否被访问
	Boolean visited[MAXVEX];   //标记已访问的点
	int i;
	EdgeNode *p;
	LinkQ *Q;
	//对所有顶点状态初始化
	for (i=0;i<GL->numV;i++)
		visited[i] = false;
	Q = new LinkQ ;
	InitQueue(Q);
	for (i=0;i<GL->numV;i++)
	{
		if (!visited[i])
		{
			visited[i]=true;
			cout<<GL->adjlist[i].data<<"  ";   //输出已访问的点
			EnQueue(Q,i);
			while(Q->rear != Q->front)
			{
				DeQueue(Q,i);
				p = GL->adjlist[i].firstedge;
				while(!p)
				{
					if (!visited[p->adjvex]) //若该点没有被访问
					{
						cout<<GL->adjlist[p->adjvex].data<<"  ";  //则输出该顶点
						visited[p->adjvex] = true;
						EnQueue(Q,p->adjvex);  //并将该顶点的下标入队
					}
					p = p->next;
				}
			}
		}
	}
}

整道题完整代码如下:

(其中包括无向图的邻接矩阵、邻接表的创建,队结构和队的部分算法创建,深度优先、广度优先算法)

#include <iostream>
#include <stdlib.h>
using namespace std;
typedef int Vtype;   //定义顶点类型
#define MAXVEX 20  //最大顶点个数

//定义图结构
struct MGraph
{
	Vtype v[MAXVEX];   //顶点表
	int arr[MAXVEX][MAXVEX];  //邻接矩阵
	int numV,numE;   //图中当前顶点数和边数
};

//定义边表结点 
struct EdgeNode
{
    Vtype adjvex;   //邻接点的下标
    EdgeNode *next;   //指向下一个邻接点
};

//定义顶点表结点
struct VertexNode
{
    Vtype data;  //顶点信息
    EdgeNode *firstedge;   //边表的头指针
};

struct GraphList
{
    VertexNode adjlist[MAXVEX];
    int numV,numE;   //图中当前顶点数和边数
};


//同时建立无向图的邻接矩阵和邻接表
void CreatGraph(MGraph *G,GraphList *GL)
{
	int i,j,k;
	EdgeNode *p;
	cout<<"输入顶点数和边数\n";
	cin>>G->numV>>G->numE;
	GL->numV = G->numV;
    GL->numE = G->numE;
	cout<<"输入顶点信息\n";
	for(i = 0;i < G->numV;i++)
	{
		cin>>G->v[i];
		GL->adjlist[i].data = G->v[i];
		GL->adjlist[i].firstedge = NULL;
	}
	//邻接矩阵初始化
	for(i = 0;i < G->numV;i++)
	{
		for(j = 0;j < G->numV;j++)
			G->arr[i][j] = 0;
	}
	//创建邻接矩阵和邻接表
	for(k = 0;k < G->numE;k++)
	{
		cout<<"输入边对应两顶点的下标(注意是下标不是信息!)\n";
		cin>>i>>j;
		G->arr[i][j] = 1;
		G->arr[j][i] = 1;

		p = new EdgeNode;
		p->adjvex = j;
		p->next = GL->adjlist[i].firstedge;
		GL->adjlist[i].firstedge = p;
		p = new EdgeNode;
		p->adjvex = i;
		p->next = GL->adjlist[j].firstedge;
		GL->adjlist[j].firstedge = p;
	}
	//打印邻接表和邻接矩阵
	cout<<"邻接矩阵为:\n";
    for(i=0;i<G->numV;i++)
	{
        for(j=0;j<G->numV;j++)
            cout<<G->arr[i][j]<<"  ";
        cout<<"\n";
	}
    cout<<"邻接表为:\n";
    for(i=0;i<GL->numV;i++)
	{
        p=GL->adjlist[i].firstedge;
		cout<<GL->adjlist[i].data;
        while(p)
		{
            cout<<"->"<<GL->adjlist[p->adjvex].data;
            p=p->next;
        }
        cout<<"\n";
    } 
}

//用邻接表结构进行深度优先搜索
typedef int Boolean;  //定义布尔类型,用于标记点是否被访问
Boolean visited[MAXVEX];   //标记已访问的点
//算法
void DFS(GraphList *GL,int i)  //从下标为i的顶点开始搜索
{
	EdgeNode *p;
	visited[i] = true;
	cout<<GL->adjlist[i].data<<"  ";   //输出已访问的点
	p = GL->adjlist[i].firstedge;
	while(p)
	{
		if(!visited[p->adjvex])
			DFS(GL,p->adjvex);   //对未访问的顶点做递归调用
		p = p->next;
	}
}
//操作
void DFSTraverse(GraphList *GL)
{
	int i;
	//对所有顶点状态初始化
	for (i=0;i<GL->numV;i++)
		visited[i] = false;
	for(i=0;i<GL->numV;i++)
	{
		if(!visited[i])
			DFS(GL,i);
	}
}


//用邻接表结构进行广度优先搜索
//创建链队列的结构
struct QNode  //结点结构
{
	int num;   //  顶点下标
	QNode *next;
};
struct LinkQ  //队列的链表结构
{
	QNode *front,*rear;   //队头队尾指针
};
//队列初始化操作
void InitQueue(LinkQ *Q)
{
	Q->front = new QNode ;	//建立头结点
	Q->front->next = NULL;
    Q->rear = Q->front;	//初始为空
}

//入队操作
int EnQueue(LinkQ *Q,int e)  //插入元素e为Q的新的队尾元素
{
	QNode *s;
	s = new QNode;
	s->num = e;
	s->next = NULL;
	Q->rear->next = s;
	Q->rear = s;
	return 1;
}
//出队操作
int DeQueue(LinkQ *Q,int e)   //若队列不空,删除Q的队头元素,用e返回其值,并返回1,否则返回0
{
	QNode *p;
	if(Q->front == Q->rear)
		return 0;
	p = Q->front->next;   //注意队列中第一个结点是没有储存编号的
	e = p->num;
	Q->front->next = p->next;
	if(Q->rear==p)
		Q->rear = Q->front;
	free(p);
	return 1;
}

//广度优先搜索主体部分
void BFSTraverse(GraphList *GL)
{
	typedef int Boolean;  //定义布尔类型,用于标记点是否被访问
	Boolean visited[MAXVEX];   //标记已访问的点
	int i;
	EdgeNode *p;
	LinkQ *Q;
	//对所有顶点状态初始化
	for (i=0;i<GL->numV;i++)
		visited[i] = false;
	Q = new LinkQ ;
	InitQueue(Q);
	for (i=0;i<GL->numV;i++)
	{
		if (!visited[i])
		{
			visited[i]=true;
			cout<<GL->adjlist[i].data<<"  ";   //输出已访问的点
			EnQueue(Q,i);
			while(Q->rear != Q->front)
			{
				DeQueue(Q,i);
				p = GL->adjlist[i].firstedge;
				while(!p)
				{
					if (!visited[p->adjvex]) //若该点没有被访问
					{
						cout<<GL->adjlist[p->adjvex].data<<"  ";  //则输出该顶点
						visited[p->adjvex] = true;
						EnQueue(Q,p->adjvex);  //并将该顶点的下标入队
					}
					p = p->next;
				}
			}
		}
	}
}


int main()
{
	MGraph *G;
	GraphList *GL;
	G = new MGraph;
	GL = new GraphList;
	CreatGraph(G,GL);  //输出邻接矩阵和邻接表
	cout<<"深度优先搜索结果为:";
	DFSTraverse (GL);   
	cout<<"\n广度优先搜索结果为:";
	BFSTraverse(GL);   
	system("pause");
	return 0;
}

输出的结果如下:

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值