深度优先搜寻递归与非递归,广度优先搜索非递归 //图遍历 #include<iostream> #include<malloc.h> #include<cstdlib> #include<cstring> using namespace std; #define MAX_INFO 10 #define MAX_VERTEX_NUM 20 #define STACK_INIT_SIZE 100// 存储空间初始分量 #define STACKINCREMENT 10//存储空间分配增量 #define OK 1 #define TRUE 1 #define ERROR 0 #define FALSE 0 typedef int SElemType; typedef int QElemType; typedef char VertexType; typedef int Status; typedef char InfoType;//信息类型 typedef enum{unvisited,visited}VisitIf; int Visited[MAX_VERTEX_NUM];//访问标志数组 Status (*VisitFunc)(VertexType e);//函数变量 VertexType Edge[2*MAX_VERTEX_NUM]; VertexType Path[MAX_VERTEX_NUM]; int IncInfo; typedef struct//栈结构 { SElemType *base; SElemType *top; int stacksize; }SqStack; typedef struct QNode//单链队列 { QElemType data; struct QNode *next; }QNode,*QueuePtr; typedef struct//队列头结点 { QueuePtr front; QueuePtr rear; }LinkQueue; typedef struct EBox//无向图的邻接多重表结构 { VisitIf mark;//访问标记 int ivex,jvex;//该边依附于两个顶点的位置 struct EBox *ilink,*jlink;//分别指向依附于这两个顶点的下一条边 InfoType *info;//该边信息指针 }EBox; typedef struct VexBox { VertexType data; EBox *firstedge;//指向第一条依附于该顶点的边 }VexBox; typedef struct { VexBox adjmulist[MAX_VERTEX_NUM]; int vexnum,edgenum;//无向图当前的定点数和边数 }AMLGraph; //栈操作 Status InitStack(SqStack &S); Status DestroyStack(SqStack &S); Status Push(SqStack &S,SElemType e); Status Pop(SqStack &S,SElemType &e); Status StackEmpty(SqStack S); //队列操作 Status InitQueue(LinkQueue &Q); Status DestroyQueue(LinkQueue &Q); Status EnQueue(LinkQueue &Q,QElemType e); Status DestroyQueue(LinkQueue &Q); Status QueueEmpty(LinkQueue Q); //遍历函数种种 int LocateVex(AMLGraph G,VertexType u); VertexType& GetVex(AMLGraph G,int v); int FirstAdjVex(AMLGraph G,VertexType v);//寻找v的第一个邻接顶点 int NextAdjVex(AMLGraph G,VertexType v,VertexType w);//返回v的(相对于w的)下一个邻接顶点 Status MarkUnvizited(AMLGraph &G);//置边的访问标记为未被访问 Status CreateGraph(AMLGraph &G);//采用邻接多重表存储结构,构造无向图G Status DFSTraverse(AMLGraph G,VertexType start,Status(*Visit)(VertexType));//从start顶点起,深度优先遍历图G(非递归算法) Status BFSTraverse(AMLGraph G,VertexType start,Status(*Visit)(VertexType));//从start顶点起,广度优先遍历图G(非递归算法) Status DFSFTraverse(AMLGraph G,Status(*Visit)(VertexType));//深度优先遍历(递归算法) void DFS(AMLGraph G,int v);//从第v个顶点出发递归深度优先遍历G Status Display(AMLGraph G);//输出无向图的邻接多重表G Status Visit(VertexType);//访问函数 void main() { AMLGraph G;//定义一个以邻接多重表为存储结构的图 cout<<“Now you have to create a graph by the information followed”<<endl; CreateGraph(G);//创建图 Display(G);//输出图 cout<<“Here is the nonrecursive DFS list:”; DFSTraverse(G,’a’,Visit);//深度非递归 cout<<“\nHere is the nonrecursive BFS list:”; BFSTraverse(G,’a’,Visit);//广度非递归 cout<<“\nHere is the recursion DFS list:”; DFSFTraverse(G,Visit);//深度递归 cout<<endl<<“That’s all,thank you!”<<endl; } Status Visit(VertexType e)//访问函数 { cout<<e<<” “; return OK; } Status InitStack(SqStack &S) { S.base=(SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType)); if(!S.base) exit(0); S.top=S.base; S.stacksize=STACK_INIT_SIZE; return OK; } Status DestroyStack(SqStack &S) { free(S.base); S.base=NULL; S.top=NULL; S.stacksize=0; return OK; } Status Push(SqStack &S,SElemType e) { if(S.top-S.base>=S.stacksize) { S.base=(SElemType*)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(SElemType)); if(!S.base) exit(0); S.top=S.base+S.stacksize; S.stacksize+=STACKINCREMENT; } *S.top++=e; return OK; } Status Pop(SqStack &S,SElemType &e) { if(S.top==S.base) return ERROR; e=*–S.top; return OK; } Status StackEmpty(SqStack S) { if(S.top==S.base) return OK; else return ERROR; } Status InitQueue(LinkQueue &Q) { Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode)); if(!Q.front) exit(0); Q.front->next=NULL; return OK; } Status DestroyQueue(LinkQueue &Q) { while(Q.front) { Q.rear=Q.front->next; free(Q.front); Q.front=Q.rear; } return OK; } Status QueueEmpty(LinkQueue Q) { if(Q.front==Q.rear) return OK; else return ERROR; } Status EnQueue(LinkQueue &Q,QElemType e) { QueuePtr p=(QueuePtr)malloc(sizeof(QNode)); if(!p) exit(0); p->data=e; p->next=NULL; Q.rear->next=p; Q.rear=p; return OK; } Status DeQueue(LinkQueue &Q,QElemType &e) { QueuePtr p; if(Q.front==Q.rear) return ERROR; p=Q.front->next; e=p->data; Q.front->next=p->next; if(Q.rear==p) Q.rear=Q.front; free(p); return OK; } int LocateVex(AMLGraph G,VertexType u)//寻找顶点在图中的位置 { int i; for(i=0;i<G.vexnum;++i) if(u==G.adjmulist[i].data) return i; return -1; } VertexType& GetVex(AMLGraph G,int v)//返回v的顶点值 { if(v>=G.vexnum||v<0) exit(0); return G.adjmulist[v].data; } int FirstAdjVex(AMLGraph G,VertexType v)//寻找v的第一个邻接顶点 { int i; i=LocateVex(G,v); if(i<0) return -1; if(G.adjmulist[i].firstedge)//v有邻接顶点 if(G.adjmulist[i].firstedge->ivex==i) return G.adjmulist[i].firstedge->jvex; else return G.adjmulist[i].firstedge->ivex; else return -1; } int NextAdjVex(AMLGraph G,VertexType v,VertexType w)//返回v的(相对于w的)下一个邻接顶点 { int i,j; EBox *p; i=LocateVex(G,v);//i是顶点v的序号 j=LocateVex(G,w); //j是顶点w的序号 if(i<0||j<0)//v或w不是G的顶点 return -1; p=G.adjmulist[i].firstedge; //p指向顶点v的第1条边 while(p) if(p->ivex==i && p->jvex!=j) //不是邻接顶点w(情况1) p=p->ilink; //找下一个邻接顶点 else if(p->jvex==i && p->ivex!=j) //不是邻接顶点w(情况2) p=p->jlink; //找下一个邻接顶点 else //是邻接顶点w break; if(p&&p->ivex==i&&p->jvex==j) //找到邻接顶点w(情况1) { p=p->ilink; if(p&&p->ivex==i) return p->jvex; else if(p&&p->jvex==i) return p->ivex; } if(p&&p->ivex==j&&p->jvex==i)//找到邻接顶点w(情况2) { p=p->jlink; if(p&&p->ivex==i) return p->jvex; else if(p&&p->jvex==i) return p->ivex; } return -1; } Status MarkUnvizited(AMLGraph &G)//置边的访问标记为未被访问 { int i; EBox *p; for(i=0;i<G.vexnum;i++) { p=G.adjmulist[i].firstedge;//指向顶点的依附指针 while(p) { p->mark=unvisited; if(p->ivex==i) p=p->ilink; else p=p->jlink; } } return OK; } Status CreateGraph(AMLGraph &G)//采用邻接多重表存储结构,构造无向图G { int i,j,k,cur=0; //VertexType s[MAX_INFO];int l; VertexType va,vb; EBox *p=NULL; cout<<“Please input the vexnum and edgenum:”; cin>>G.vexnum>>G.edgenum; //信息暂时不录入 cout<<“Please intput “<<G.vexnum<<” values of vertexs:”<<endl;//输入顶点向量的值 for(i=0;i<G.vexnum;++i) { cin>>G.adjmulist[i].data; G.adjmulist[i].firstedge=NULL; } cout<<“Please input the Edges orderly by two vertexs:”<<endl;//两点确定一条边 for(k=0;k<G.edgenum;++k)//构造表结点链表 { cin>>va>>vb;//读入两个顶点 Edge[cur++]=va; Edge[cur++]=vb; i=LocateVex(G,va); j=LocateVex(G,vb);//找到两端的位置 p=(EBox*)malloc(sizeof(EBox)); p->mark=unvisited;//设初值 p->ivex=i;//顶点的位置 p->jvex=j; p->info=NULL;//信息 p->ilink=G.adjmulist[i].firstedge;//插在表头 G.adjmulist[i].firstedge=p; p->jlink=G.adjmulist[j].firstedge;//插在表头 G.adjmulist[j].firstedge=p;//插入j链表尾部 /* if(IncInfo)//信息暂时不输入 { cout<<“Please input the Info about the edge: “; cin>>s; l=strlen(s); if(l) { p->info=(char*)malloc((l+1)*sizeof(char)); p->info=s; } }*/ } return OK; } Status DFSFTraverse(AMLGraph G,Status(*Visit)(VertexType))//深度非递归 { VisitFunc=Visit;//使用全局变量VisitFunc int v; for(v=0;v<G.vexnum;v++) Visited[v]=FALSE;//初始化 for(v=0;v<G.vexnum;v++) if(!Visited[v]) DFS(G,v);//对尚未访问的顶点调用DFS return OK; } void DFS(AMLGraph G,int v)//从第v个顶点出发递归深度优先遍历G { int w; Visited[v]=TRUE; VisitFunc(G.adjmulist[v].data); for(w=FirstAdjVex(G,v);w>=0;w=NextAdjVex(G,v,w)) if(!Visited[w]) DFS(G,w); } Status DFSTraverse(AMLGraph G,VertexType start,int(*visit)(VertexType))//从start顶点起,深度优先遍历图G(非递归算法) { int v,w,u; SqStack S,S2; InitStack(S); InitStack(S2); w=LocateVex(G,start); for(v=0;v<G.vexnum;v++) Visited[v]=0; for(v=0;v<G.vexnum;v++) if(!Visited[(v+w)%G.vexnum]) { Push(S,(v+w)%G.vexnum); while(!StackEmpty(S)) { Pop(S,u); if(!Visited[u]) { Visited[u]=1; visit(G.adjmulist[u].data); for(w=FirstAdjVex(G,G.adjmulist[u].data);w>=0; w=NextAdjVex(G,G.adjmulist[u].data,G.adjmulist[w].data)) if(!Visited[w]) Push(S2,w); while(!StackEmpty(S2)) { Pop(S2,u); Push(S,u); } } } } return OK; } Status BFSTraverse(AMLGraph G,VertexType start,int(*Visit)(VertexType))//从start顶点起,广度优先遍历图G { int v,u,w,z; LinkQueue Q; for(v=0;v<G.vexnum;v++) Visited[v]=0;//置初值 InitQueue(Q); z=LocateVex(G,start); for(v=0;v<G.vexnum;v++) if(!Visited[(v+z)%G.vexnum])//v尚未访问 { Visited[(v+z)%G.vexnum]=1;//设置访问标志为TRUE(已访问) Visit(G.adjmulist[(v+z)%G.vexnum].data); EnQueue(Q,(v+z)%G.vexnum); while(!QueueEmpty(Q))//队列不空 { DeQueue(Q,u); for(w=FirstAdjVex(G,G.adjmulist[u].data);w>=0;w=NextAdjVex(G,G.adjmulist[u].data,G.adjmulist[w].data)) if(!Visited[w]) { Visited[w]=1; Visit(G.adjmulist[w].data); EnQueue(Q,w); } } } return OK; } Status Display(AMLGraph G)//输出无向图的邻接多重表G { int i; EBox *p; MarkUnvizited(G); cout<<“This graph has “<<G.vexnum<<” Vexs:”<<endl; for(i=0;i<G.vexnum;++i) cout<<G.adjmulist[i].data<<” “; cout<<endl<<“This graph has “<<G.edgenum<<” Edges:”<<endl; for(i=0;i<G.vexnum;i++) { p=G.adjmulist[i].firstedge; while(p) { if(p->ivex==i)//边的i端与该顶点有关 { if(!p->mark)//只输出一次 { cout<<G.adjmulist[i].data<<‘-‘<<G.adjmulist[p->jvex].data<<endl; p->mark=visited; //if(p->info)//输出附带信息 //cout<<“The Info:”<<p->info<<ends; } p=p->ilink; } else//边的j端与该顶点有关 { if(!p->mark)//只输出一次 { cout<<G.adjmulist[p->ivex].data<<‘-‘<<G.adjmulist[i].data<<endl; p->mark=visited; // if(p->info)//输出附带信息 // cout<<“The Info:”<<p->info<<ends; } p=p->jlink; } } } return OK; } |