标签:算法导论 广度优先搜索bfs 深度优先搜索dfs 树边 c++
图有两种标准的表示方法,即邻接矩阵和邻接表(通常邻接矩阵用于稠密图,邻接表用于稀疏图)。如下:
对于图的搜索有两种方法:深度优先搜索 & 广度优先搜索。
广度优先搜索是将已发现和未发现顶点之间的边界沿其广度方向向外扩展。亦即算法首先会发现和s距离为k的所有点,然后才会发现和s距离为k+1的其他顶点。
伪代码:
EG:
运行时间:O(V+E)。
在深度优先搜索中,对于最新发现的顶点,如果他还有以此为起点而为探测到的变,就沿着此边继续探测下去。当顶点v的所有变都已被探寻后,搜索将回溯到发现顶点v有起始点那条边。
伪代码:
EG:
运行时间:O(V+E).
========================================================================================================================
广度优先搜索完整代码:
#include<iostream> #include<queue> #include<climits> #define UDG 0 #define DG 1 #define WHITE 2 #define GRAY 3 #define BLACK 4 using namespace std; typedef char vType; typedef struct gEdge{ vType adjVertex; //the adjacency vertex pointed by this edge. int weight; //the weight of this edge gEdge *nextEdge; //Point to the next edge }gEdge; typedef struct gVertex{ vType key; // the key of the vertex int color; int d; vType pai; gEdge *firstEdge; // point to the first edge attached to the vertex; }gVertex; typedef struct ALGraph{ int Vnum; int Enum; int kind; //the kind of Graph gVertex *HeadVertex; }ALGraph; typedef struct edge{ vType start; vType end; }edge; int Locate(ALGraph &G,vType s) {//locate the start vertex of one edge in head vertex of the graph for(int i=0;i<G.Vnum;i++) if(G.HeadVertex[i].key == s) return i; return -1; } void LinkEdgeToGraph(ALGraph &G, edge e) { gEdge *arc=new gEdge(); arc->adjVertex=e.end; int headV_i=Locate(G,e.start); arc->nextEdge=G.HeadVertex[headV_i].firstEdge; G.HeadVertex[headV_i].firstEdge = arc; } void Graph_Create(ALGraph &G, vType V[], edge E[]) { //init the head vertex G.HeadVertex= new gVertex[G.Vnum]; for(int i=0;i<G.Vnum;i++){ G.HeadVertex[i].key=V[i]; G.HeadVertex[i].firstEdge=NULL; } //add edge to head vertex in order to create a graph if(G.kind == DG) //undirected graph for(int i=0; i<G.Enum; i++) LinkEdgeToGraph(G,E[i]); if(G.kind == UDG) // directed graph for(int i=0; i<G.Enum; i++) { LinkEdgeToGraph(G,E[i]); // link again after reversed edge temp; temp.start = E[i].end; temp.end = E[i].start; LinkEdgeToGraph(G,temp); } } void Graph_Print(ALGraph G) { for(int i=0; i<G.Vnum; i++) { cout<<G.HeadVertex[i].key; gEdge *p = G.HeadVertex[i].firstEdge; while(p != NULL) { cout<<" --> "<< p->adjVertex; p = p->nextEdge; } cout<<endl; } } /* void Q_Print(queue<vType> Q) { cout<<"The Q is:"; while(!Q.empty()) { cout<<Q.front()<<" "; Q.pop(); } cout<<endl; } */ vType *ALGraph_BFS(ALGraph &G, vType s) { queue<vType> Q; vType *BFSResult=new vType[G.Vnum]; //label the vertex:the starting vertex becomes GRAY,the others become WHITE... for(int i=0; i<G.Vnum; i++) { gVertex *hVertex=&G.HeadVertex[i]; hVertex->color = WHITE; hVertex->d = INT_MAX; hVertex->pai = '0'; if(hVertex->key == s) { hVertex->color = GRAY; hVertex->d = 0; } } //Clear the Q while(!Q.empty()) // making the queue Q empty Q.pop(); Q.push(s); // s enter queue Q //Searching layer by layer int r_i=0; while(!Q.empty()) { vType u,v; u= Q.front();Q.pop(); //delete the front element of the Q BFSResult[r_i] = u; //store the result into Array BFSResult r_i++; int h_i=Locate(G,u); gVertex *hu = &G.HeadVertex[h_i]; gEdge *p = G.HeadVertex[h_i].firstEdge; while(p) { v = p->adjVertex; h_i = Locate(G,v); gVertex *hv = &G.HeadVertex[h_i]; if(hv->color == WHITE) { hv->color = GRAY; hv->d = hv->d+1; hv->pai = u; Q.push(v); } p = p->nextEdge; } hu->color = BLACK; } return BFSResult; } int main() { vType V[]={'s','w','r','v','t','x','u','y'}; edge E[]={{'r','v'},{'r','s'},{'s','w'},{'w','t'},{'w','x'},{'t','u'},{'t','x'},{'x','u'},{'x','y'},{'u','y'}}; ALGraph G; G.Vnum=sizeof(V)/sizeof(vType); G.Enum=sizeof(E)/sizeof(edge); G.kind=UDG; //the kind of Graph Graph_Create(G,V,E); cout<<"---------------Create Graph-----------------"<<endl; cout<<"The created graph is:"<<endl; Graph_Print(G); cout<<"---------------BFS Graph--------------------"<<endl; cout<<"Please input the starting position:"; vType s; cin>>s; vType *BFSResult = new vType[G.Vnum]; BFSResult=ALGraph_BFS(G,s); cout<<"The result of BFS is:"<<endl; for(int i=0; i<G.Vnum; i++) cout<<BFSResult[i]<<" "; cout<<endl; return 0; }
深度优先搜索完整代码:
#include<iostream> #include<iomanip> using namespace std; #define UDG 0 #define DG 1 #define WHITE 0 #define GRAY 1 #define BLACK 2 #define NONE 0 #define TREE 1 #define BACK 2 #define FORWARD 3 #define CROSS 4 typedef char vType; typedef struct gEdge{ vType adjVertex; //the adjacency vertex pointed by this edge. int weight; //the weight of this edge int type; //the type of edge gEdge *nextEdge; //Point to the next edge }gEdge; typedef struct gVertex{ vType key; // the key of the vertex int color; int d,f; // the discovered time and the finished time vType pai; // the parent node's key after searching gEdge *firstEdge; // point to the first edge attached to the vertex; }gVertex; typedef struct ALGraph{ int Vnum; int Enum; int kind; //the kind of Graph gVertex *HeadVertex; }ALGraph; typedef struct edge{ vType start; vType end; }edge; int Locate(ALGraph &G,vType s) {//locate the start vertex of one edge in head vertex of the graph for(int i=0;i<G.Vnum;i++) if(G.HeadVertex[i].key == s) return i; return -1; } void LinkEdgeToGraph(ALGraph &G, edge e) { gEdge *arc=new gEdge(); arc->adjVertex=e.end; int headV_i=Locate(G,e.start); arc->nextEdge=G.HeadVertex[headV_i].firstEdge; G.HeadVertex[headV_i].firstEdge = arc; } void Graph_Create(ALGraph &G, vType V[], edge E[]) { //init the head vertex G.HeadVertex= new gVertex[G.Vnum]; for(int i=0;i<G.Vnum;i++){ G.HeadVertex[i].key=V[i]; G.HeadVertex[i].firstEdge=NULL; } //add edge to head vertex in order to create a graph if(G.kind == DG) //undirected graph for(int i=0; i<G.Enum; i++) LinkEdgeToGraph(G,E[i]); if(G.kind == UDG) // directed graph for(int i=0; i<G.Enum; i++) { LinkEdgeToGraph(G,E[i]); // link again after reversed edge temp; temp.start = E[i].end; temp.end = E[i].start; LinkEdgeToGraph(G,temp); } } void Graph_Print(ALGraph G) { for(int i=0; i<G.Vnum; i++) { cout<<G.HeadVertex[i].key; gEdge *p = G.HeadVertex[i].firstEdge; while(p != NULL) { cout<<" --> "<< p->adjVertex; p = p->nextEdge; } cout<<endl; } } void EdgeType_Print(ALGraph G) { for(int i=0; i<G.Vnum; i++) { gEdge *p = G.HeadVertex[i].firstEdge; while(p) { cout<<G.HeadVertex[i].key<<"-->"<<p->adjVertex<<":"; switch(p->type) { case TREE: cout<<"Tree edge"<<endl; break; case BACK: cout<<"Back edge"<<endl; break; case FORWARD: cout<<"Forward edge"<<endl; break; case CROSS: cout<<"Cross edge"<<endl; break; } p = p->nextEdge; } } } /*--------------------DFS Alogithms-----------------------*/ int time0; int r_i=0; void Graph_DFSVisit(ALGraph &G, gVertex *u, vType *r) { time0 = time0 +1; //white vertex u has just been discovered u->d = time0 ; u->color = GRAY; gEdge *p = u->firstEdge; while(p) { vType v = p->adjVertex; int h_i=Locate(G,v); gVertex *hv = &G.HeadVertex[h_i]; //classify the edge and recursive searching if( hv->color == WHITE) { hv->pai = u->key; Graph_DFSVisit(G,hv,r); p->type = TREE; //Tree edge } else if(hv->color == GRAY){ p->type = BACK; //Back edge } else if(hv->color == BLACK) { if(u->d < hv->d) p->type = FORWARD; //Forward edge else p->type = CROSS; //Cross edge } p = p->nextEdge; } u->color = BLACK; //backen u;it is finished r[r_i++]=u->key; //store the dfs result into array r time0 = time0 +1; u->f = time0; } void ALGraph_DFS(ALGraph &G, vType *result) { //init all the vertex gVertex *u; for(int i=0; i<G.Vnum; i++) { u = &G.HeadVertex[i]; u->color = WHITE; u->pai = '0'; } time0 = 0; //time stamp //explore every vertex for(int i=0; i<G.Vnum; i++) { u = &G.HeadVertex[i]; if(u->color == WHITE) Graph_DFSVisit(G,u,result); } } /*----------------------------------------------*/ int main() { vType V[]={'u','x','v','y','w','z'}; edge E[]={{'u','x'},{'u','v'},{'x','v'},{'v','y'},{'y','x'},{'w','y'},{'w','z'},{'z','z'}}; ALGraph G; G.Vnum=sizeof(V)/sizeof(vType); G.Enum=sizeof(E)/sizeof(edge); G.kind=DG; //the kind of Graph Graph_Create(G,V,E); cout<<"---------------Create Graph-----------------"<<endl; cout<<"The created graph is:"<<endl; Graph_Print(G); cout<<"---------------DFS Graph--------------------"<<endl; vType *DFSResult = new vType[G.Vnum]; ALGraph_DFS(G,DFSResult); cout<<"The result of DFS is:"<<endl; for(int i=0; i<G.Vnum; i++) cout<<DFSResult[i]<<" "; cout<<endl; cout<<"The discovered time and finished time respectivly is:"<<endl; for(int i=0; i<G.Vnum; i++) cout<<G.HeadVertex[i].key<<setw(4)<<G.HeadVertex[i].d<<setw(4)<<G.HeadVertex[i].f<<endl; cout<<"The Edge type information is:"<<endl; EdgeType_Print(G); cout<<"--------------------------------------------"<<endl; return 0; }
【注:若有错误,请指正~~~】
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:算法导论 广度优先搜索bfs 深度优先搜索dfs 树边 c++
原文地址:http://blog.csdn.net/u010183397/article/details/46961585