数据结构(C语言版)规范代码之图(邻接多重表遍历)
来源:互联网 发布:js 时间排序函数 编辑:程序博客网 时间:2024/06/05 16:15
深度优先搜寻递归与非递归,广度优先搜索非递归
//图遍历
#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;
}
- 数据结构(C语言版)规范代码之图(邻接多重表遍历)
- 数据结构(C语言版)规范代码之图(邻接矩阵与邻接表)
- 数据结构(C语言版)规范代码之图(邻接表的拓扑排序)
- 数据结构C语言版之邻接表(各种遍历)
- 数据结构(C语言版)规范代码之树(1)
- 数据结构(C语言版)规范代码之栈
- 数据结构(C语言版)规范代码之队列
- 数据结构C语言版之邻接矩阵(遍历)
- 数据结构与算法(C语言版)__邻接表
- 数据结构(C语言版)规范代码之树(2线索化)
- 数据结构(C语言版)规范代码之树(3赫夫曼编码)
- 数据结构之图的邻接多重表
- 数据结构(c语言版)之顺序表
- 数据结构之线性表(C语言版)
- 数据结构:无向图的邻接多重表存储表示 (c实现)
- 数据结构:图(邻接多重表存储 c++实现)
- 数据结构之非递归遍历和层次遍历(C语言版)
- 数据结构(C语言版)
- [HKEY_LOCAL_MACHINE\init]键值的含义
- proc文件系统解析
- 面试,杯具了也可以从中找到不足
- VC和Perl的互相调用收集
- POJ 1573 Robot Motion模拟
- 数据结构(C语言版)规范代码之图(邻接多重表遍历)
- 2B
- 35岁的程序员,何去何从?
- JavaScript学习思索
- java多线程实现火车售票系统 以及java中的同步的实现 同步块 和同步方法同时 同步
- 数据库还原
- C语言测试题
- Hibernate的多条件查询通用方法(查询条件个数不限,能进行模糊、精确2种查...
- 字符串和数字的left 函数实现