数据结构(C语言版)规范代码之图(邻接多重表遍历)

深度优先搜寻递归与非递归,广度优先搜索非递归

//图遍历
#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;
}

    原文作者:数据结构之图
    原文地址: https://blog.csdn.net/erzhongshiren/article/details/6655323
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞