关于图的广度优先搜索算法的思考.

节点的直接相所谓图的广度优先搜索:对于一个无向或者有向联通图,抓住任意一个节点(假设是s)开始,找到与这个节点直接相连的所有节点,这些节点的深度(depth)是相同的(注意这里所说的深度:是在广度优先遍历的过程中会形成一颗广度优先搜索树,深度即位这个节点在这棵树中的深度,也就是从s到该节点的最短路径),即在广度优先搜索树中的同一层,然后再去找这些节点的直接相连的节点,找到的这些子节点比其父节点的深度+1,这样直至所有邻节点找到完以后结束

现在详细说一下广度优先搜索的过程:

首先是准备工作,将所有的节点标记为"未发现",初始化一个队列queue,在搜索的过程中要用

从一个节点s开始,其depth为0,将s放入queue中.

然后在queue不空的情况下,弹出队列的最前面的一个节点u,找其在图中直接相邻的节点,将找到的节点放入队列queue中,找到后深度值标记为其父节点(刚弹出的节点为其父亲节点)的深度加一,还有要标记这些节点已经被"发现",因为在后面的节点搜索中这些节点有可能被再次搜索到,这个时候,这些节点已经被"发现"过了,不再进行深度标记,这样直接相邻的节点全部找到标记完成后,(即u节点的所在的边搜索完成),程序走到了前面的循环条件判断队列queue是否为空,不空的情况下继续重复上述工作,空即搜索完成.

广度优先搜索树的意义:

广度优先搜索树里从根节点到任意节点v的简单路径即为s到v的"最短路径",即包含最少的边的路径.

graph.h文件:

#ifndef GRAPH_H
#define _GRAPH_H
#define  DEFAULT_VERTEX_SIZE 10
#include<string.h>
#include<queue>
template<class Type>
class Graph;
class Edge
{
		public:
				Edge(int num):dest(num),link(NULL)
		{}
				~Edge()
				{}
				int dest;
				Edge* link;
};
template<class Type>
class Vertex
{
		friend Graph<Type>;
		public:
		Vertex():data(Type()),adj(NULL)
		{}
		~Vertex()
		{}
		private:
		Edge *adj;
		Type data;
};
template<class Type>
class Graph
{
		public:
				Graph(int sz=DEFAULT_VERTEX_SIZE)
				{
						MaxVertices=sz>DEFAULT_VERTEX_SIZE?sz:DEFAULT_VERTEX_SIZE;
						NumVertices=NumEdge=0;
						NodeTable=new Vertex<Type>[MaxVertices];
				}
				~Graph()
				{
						Edge *t;
						for(int i=0;i<NumVertices;++i)
						{
								Edge *w;
								t=NodeTable[i].adj;
								while(t!=NULL)
								{
										w=t;
										t=t->link;
										delete w;
								}
						}
						delete[] NodeTable;

						//
				}
				int GetPosOfVertex(const Type &v)const
				{
						for(int i=0;i<NumVertices;++i)
						{
								if(NodeTable[i].data==v)
										return i;
						}
						return -1;

				}
				void InsertVertex(const Type &val)
				{
						if(NumVertices<MaxVertices)
						{
								NodeTable[NumVertices++].data=val;
						}
				}
				bool InsertEdge(const Type &vertex1, const Type &vertex2)
				{
						int v1 = GetPosOfVertex(vertex1);
						int v2 = GetPosOfVertex(vertex2);
						if(v1==-1 || v2==-1)
								return false;
						//v1 --> v2
						Edge *e = new Edge(v2);
						e->link = NodeTable[v1].adj;
						NodeTable[v1].adj = e;
						//v2 --> v1
						e = new Edge(v1);
						e->link = NodeTable[v2].adj;
						NodeTable[v2].adj = e;
						NumEdge++;
						return true;
				}

				/*
				   bool InsertEdge(const Type &v1,const Type &v2)
				   {
				   int V1=GetPosOfVertex(v1);
				   int V2=GetPosOfVertex(v2);
				   if(V1==-1||V2==-1)
				   return false;
				//v1-->v2
				cout<<"v1: "<<V1<<"  v2:  "<<V2<<endl;
				Edge *s=new Edge(V2);
				s->link=NodeTable[V1].adj;
				NodeTable[V1].adj=s;
				//v2-->v1
				Edge *s1=new Edge(V1);
				s1->link=NodeTable[V2].adj;
				NodeTable[V1].adj=s1;
				++NumEdge;
				return true;
				}
				 */
				int NumOfVertex()const
				{
						return NumVertices;
				}
				int NumOfEdge()const
				{
						return NumEdge;
				}
				Type GetValueByIndex(int i)
				{
						if(i<=NumVertices&&i>=0)
								return NodeTable[i].data;
				}
				int GetFirstNeighbor(const Type &vertex)const
				{
						int v=GetPosOfVertex(vertex);
						if(v==-1)
								return -1;
						if(    NodeTable[v].adj!=NULL)
								return NodeTable[v].adj->dest;
						else
								return -1;

				}
				int GetNextNeighbor(const Type &vertex1,const Type &vertex2)const
				{
						int v1=GetPosOfVertex(vertex1);
						int v2=GetPosOfVertex(vertex2);
						if(v1==-1||v2==-1)
								return -1;
						if(NodeTable[v1].adj==NULL)
								return -1;
						Edge *t=NodeTable[v1].adj;
						while(t!=NULL&&t->dest!=v2)
								t=t->link;
						if(t==NULL)
								return -1;
						else
								if(t->link!=NULL)
										return t->link->dest;
								else
										return -1;
				}

				bool RemoveEdge(const Type &vertex1,const Type &vertex2)
				{
						int v1=GetPosOfVertex(vertex1);
						int v2=GetPosOfVertex(vertex2);
						if(v1==-1||v2==-1)
								return false;
						Edge *t=NodeTable[v1].adj;
						Edge *p=t;
						while(t!=NULL&&t->dest!=v2)
						{
								p=t;
								t=t->link;
						}
						if(t==NULL)
								return false;
						else
						{
								if(p==t)
								{
										Edge *w=NodeTable[v1].adj;
										NodeTable[v1].adj=NodeTable[v1].adj->link;
										delete w;
								}
								else
								{
										Edge *w=p->link;
										p->link=t->link;
										delete w;
								}
								//
								t=p=NodeTable[v2].adj;
								while(t->dest!=v1)
								{
										p=t;
										t=t->link;
								}
								if(t==p)
								{
										Edge *w=NodeTable[v2].adj;
										NodeTable[v2].adj=NodeTable[v2].adj->link;
										delete w;
								}
								else
								{    
										Edge *w=p->link;
										p->link=t->link;
										delete w;
								}
								--NumEdge;
								return true;
						}

				}
				bool RemoveVertex(const Type &vertex)
				{
						int v=GetPosOfVertex(vertex);
						if(v==-1)
								return false;
						Edge* t=NodeTable[v].adj;
						while(t!=NULL)
						{
								Edge *p=NodeTable[t->dest].adj;
								Edge *p1=p;
								while(p!=NULL)
								{
										while(p->dest!=v)
										{
												p1=p;
												p=p->link;
										}
										if(p==p1)
										{
												Edge *w=NodeTable[t->dest].adj;
												NodeTable[t->dest].adj=NodeTable[t->dest].adj->link;
												delete w;
												break;
										}
										else
										{
												Edge* w=p1->link;
												p1->link=p->link;
												delete w;
												break;
										}
								}
								p1=t;
								t=t->link;
								delete p1;
								--NumEdge;
						}
						if(v!=NumVertices-1)
						{
								NodeTable[v].data=NodeTable[NumVertices-1].data;
								NodeTable[v].adj=NodeTable[NumVertices-1].adj;
								Edge *t1=NodeTable[NumVertices-1].adj;
								while(t1!=NULL)
								{
										Edge *p3=NodeTable[t1->dest].adj;
										while(p3->dest!=NumVertices-1)
												p3=p3->link;
										p3->dest=v;

										t1=t1->link;
								}
						}
						--NumVertices;
						return true;
				}
				void DFSTraverse()//深度遍历
				{
						bool *visited=new bool[NumVertices];
						for(int i=0;i<NumVertices;++i)
								visited[i]=false;
						for(int i=0;i<NumVertices;++i)
								if(!visited[i])
										DFS(i,visited);
				}
				void DFS(int v,bool *&visited)
				{
						if(v<=-1&&v>=NumVertices)
								return ;
						visited[v]=true;
						cout<<NodeTable[v].data<<"  ";
						for(int w=GetFirstNeighbor(GetValueByIndex(v));w>=0;w=GetNextNeighbor(GetValueByIndex(v),GetValueByIndex(w)))
								if(!visited[w])
										DFS(w,visited);

				}
				void DFSTraverse_1(Type val)
				{
						bool *visited=new bool[NumVertices];
						for(int i=0;i<NumVertices;++i)
								visited[i]=false;
						int x=GetPosOfVertex(val);
						visited[x]=true;
						cout<<NodeTable[x].data<<"  ";
						for(int w=GetFirstNeighbor(val);w>=0;w=GetNextNeighbor(val,GetValueByIndex(w)))
						{
								if(!visited[w])
								{
										visited[w]=true;
										cout<<NodeTable[w].data<<"  ";
								}
						}
						for(int i=0;i<NumVertices;++i)
						{
								if(!visited[i])
								{
										visited[i]=true;
										cout<<NodeTable[i].data<<"  ";
										for(int w=GetFirstNeighbor(GetValueByIndex(i));w>=0;w=GetNextNeighbor(GetValueByIndex(i),GetValueByIndex(w)))
												if(!visited[w])
												{
														visited[w]=true;
														cout<<NodeTable[w].data<<"  ";
												}
								}

						}

				}
				void BFSTraverse()//广度遍历
				{
						cout<<"广度优先搜索树:";
						bool *visited=new bool[NumVertices];
						int *distance = new int[NumVertices];
						memset(distance,0,sizeof(int)*NumVertices);
						for(int i=0;i<NumVertices;++i)
								visited[i]=false;
						queue<int>  Q;

						distance[0] = 0;
						for(int i=0;i<NumVertices;++i)
						{
								if(!visited[i])
								{
										visited[i]=true;
										cout<<NodeTable[i].data<<" : depth="<<distance[i]<<"	";
								}
								Q.push(i);
								while(!Q.empty())
								{
										int u=Q.front();
										Q.pop();
										Edge *s=NodeTable[u].adj;
										while(s!=NULL)
										{
												if(!visited[s->dest])
												{
														visited[s->dest]=true;
														Q.push(s->dest);

														distance[s->dest] = distance[u] + 1;
														cout<<NodeTable[s->dest].data<<" : depth="<<distance[s->dest]<<"	";
														
												}
												s=s->link;
										}
								}
						}
				}
				void BFSTraverse_1(Type v)
				{
						bool *visited=new bool[NumVertices];
						queue<int> Q;
						int x=GetPosOfVertex(v);
						if(x==-1)
								return;
						Q.push(x);
						cout<<v<<"  ";
						visited[x]=true;
						Edge *s=NodeTable[x].adj;
						while(s!=NULL)
						{    
								if(!visited[s->dest])
								{
										visited[s->dest]=true;
										Q.push(s->dest);
										cout<<NodeTable[s->dest].data<<"  ";
								}
								s=s->link;
						}
						while(!Q.empty())
						{
								int u=Q.front();
								Q.pop();
								s=NodeTable[u].adj;
								while(s!=NULL)
								{
										if(!visited[s->dest])
										{
												visited[s->dest]=true;
												cout<<NodeTable[s->dest].data<<"  ";
												Q.push(s->dest);
										}
										s=s->link;
								}

						}
				}
				void ShowGraph()
				{
						for(int i=0;i<NumVertices;++i)
						{
								cout<<i<<"  "<<NodeTable[i].data<<"  "<<"-->";
								Edge* e=NodeTable[i].adj;
								while(e!=NULL)
								{
										cout<<e->dest<<"-->";
										e=e->link;
								}
								cout<<"NUL"<<endl;;
						}
				}
		private:
				Vertex<Type>*NodeTable;
				int MaxVertices;
				int NumVertices;
				int NumEdge;
};

#endif

test.cpp:

#include<iostream>

using namespace std;
#include"./graph.h"

int main()
{
	Graph<char> gh;
	gh.InsertVertex('s');
	gh.InsertVertex('r');
	gh.InsertVertex('v');
	gh.InsertVertex('w');
	gh.InsertVertex('t');
	gh.InsertVertex('x');
	gh.InsertVertex('y');
	gh.InsertVertex('u');
	gh.InsertEdge('s','r');
	gh.InsertEdge('s','w');
	gh.InsertEdge('v','r');
	gh.InsertEdge('w','t');
	gh.InsertEdge('w','x');
	gh.InsertEdge('t','x');
	gh.InsertEdge('u','x');
	gh.InsertEdge('u','y');
	gh.InsertEdge('t','u');
	gh.InsertEdge('x','y');
	gh.ShowGraph();
	cout<<endl;
	gh.BFSTraverse();
	cout<<endl;
	gh.ShowGraph();
	cout<<endl;
/*	gh.DFSTraverse();
	cout<<endl;
	gh.ShowGraph();
	cout<<endl;
*/

	return 0;
}

测试结果:

./test
0  s  -->3-->1-->NUL
1  r  -->2-->0-->NUL
2  v  -->1-->NUL
3  w  -->5-->4-->0-->NUL
4  t  -->7-->5-->3-->NUL
5  x  -->6-->7-->4-->3-->NUL
6  y  -->5-->7-->NUL
7  u  -->4-->6-->5-->NUL

广度优先搜索树:s : depth=0	w : depth=1	r : depth=1	x : depth=2	t : depth=2	v : depth=2	y : depth=3	u : depth=3	



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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值