图的遍历。


数据结构。

上机实验:图的深度优先搜索遍历和广度优先搜索遍历。拓扑排序。


测试数据:

6 8
A B C D E F
A B
A C
A D
C E
C B
C E
D E
F D
F E


测试结果:

请输入图的顶点数,边数:6 8
请输入6个顶点的值:
A B C D E F
请输入8条弧的弧尾 弧头:
A B
A C
A D
C E
C B
C E
D E
F D
深度优先搜索遍历的结果为:
A D E C B F


广度优先搜索遍历的结果为:
A D C B E F


F A C B D E 为一个拓扑序列。


#include <stdio.h>
#include <stdlib.h>
#define MAX_VERTEX_NUM 20	//最大顶点数
#define stackinitsize 100
#define stackincrement 10
#define ok 1
#define error 0
#define overflow -1
typedef char VertexType;	//顶点类型
typedef int status;
typedef int SElemType;  	//定义栈元素为整型
typedef int QElemType;		//定义队列元素为整型 
struct ElemType
{
	int adjvex;			//该弧所指向的顶点的位置,无其他弧信息 
};
typedef struct ArcNode			//表结点,存弧的信息 
{
	ElemType data;		//除指针以外的部分都属于ElemType 
	ArcNode *nextarc;	//指向下一条弧的指针 
}ArcNode,*parcnode;

typedef struct			//头结点,存顶点的信息 
{
	VertexType data;	//顶点信息 
	ArcNode *firstarc;	//第1个表结点的地址,指向第1条依附该顶点的弧的指针 
}VNode,AdjList[MAX_VERTEX_NUM];

struct ALGraph			//邻接表结构
{
	AdjList vertices;	//头结点(顶点)数组 
	int vexnum,arcnum;	//图的当前顶点数和弧数 
};
//栈的操作
typedef struct SqStack
{
	SElemType *base;
	SElemType *top;
	int stacksize;
}SqStack;
status InitStack(SqStack &S)
{
	S.base = (SElemType *)(malloc)(stackinitsize * sizeof(SElemType));
	if(!S.base) exit(overflow);
	S.top=S.base;
	S.stacksize=stackinitsize;
	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(overflow);
		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 1;
	else return 0;
}

//链队列的操作
typedef struct QNode
{
	QElemType data;
	QNode *next;
}*QueuePtr;
struct LinkQueue
{
	QueuePtr front,rear;
};
void InitQueue(LinkQueue &Q)
{
	Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode));
	if(!Q.front)
		exit(overflow);
	Q.front->next=NULL;
}
status QueueEmpty(LinkQueue &Q)
{
	if(Q.front->next==NULL)
		return 1;
	else
		return 0;
}
void EnQueue(LinkQueue &Q,QElemType e)
{
	QueuePtr p;
	p=(QueuePtr)malloc(sizeof(QNode));
	if(!p) exit(overflow);
	p->data=e;
	p->next=NULL;
	Q.rear->next=p;
	Q.rear=p;
}
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;
}
//图的操作
bool visited[MAX_VERTEX_NUM]; 	//访问标记数组 
void ListInsert(parcnode &L,int i,ElemType e)	//插入函数 
{
	parcnode s;
	s=(ArcNode *)malloc(sizeof(ArcNode));
	s->data=e;
	s->nextarc=L;
	L=s;
}

int LocateVex(ALGraph G,VertexType u)
{
	int i;
	for(i=0;i<G.vexnum;++i)
	{
		if(G.vertices[i].data==u) return i;
	}
	return -1;
}
void CreateGraph(ALGraph &G)	//采用邻接表存储结构,构造有向图 
{
	int i,j,k;
	ElemType e;
	VertexType v1,v2;
	printf("请输入图的顶点数,边数:");
	scanf("%d%d",&G.vexnum,&G.arcnum);
	getchar();
	printf("请输入%d个顶点的值:\n",G.vexnum);
	for(i=0;i<G.vexnum;++i)
	{
		scanf("%c",&G.vertices[i].data);
		getchar();
		G.vertices[i].firstarc=NULL;
	}
	printf("请输入%d条弧的弧尾 弧头:\n",G.arcnum);
	for(k=0;k<G.arcnum;++k)
	{
		scanf("%c %c",&v1,&v2);
		getchar();
		i=LocateVex(G,v1);	//弧头 
		j=LocateVex(G,v2);	//弧尾
		e.adjvex=j;
		ListInsert(G.vertices[i].firstarc,1,e);
	}
}
void Visit(VertexType e)
{
	printf("%c ",e);
}
void DFS(ALGraph G,int v,void(*Visit)(VertexType))		//深度优先搜索遍历
{
	ArcNode *p;
	visited[v]=true;
	Visit(G.vertices[v].data);
	for(p=G.vertices[v].firstarc;p;p=p->nextarc)
		if(!visited[p->data.adjvex])
			DFS(G,p->data.adjvex,Visit);
}
void DFSTraverse(ALGraph G,void(*Visit)(VertexType))
{
	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,Visit);
	}
	printf("\n\n");
}

void BFSTraverse(ALGraph G,void(*Visit)(VertexType))	//广度优先搜索遍历
{
	ArcNode *p;
	LinkQueue Q;
	int v,u;
	for(v=0;v<G.vexnum;++v)
		visited[v]=false;
	InitQueue(Q);
	for(v=0;v<G.vexnum;++v)
	{
		if(!visited[v])
		{ 
			visited[v]=true;
			Visit(G.vertices[v].data);
			EnQueue(Q,v);
			while(!QueueEmpty(Q))
			{
				DeQueue(Q,u);
				for(p=G.vertices[u].firstarc;p;p=p->nextarc)
					if(!visited[p->data.adjvex])
					{
						visited[p->data.adjvex]=true;
						Visit(G.vertices[p->data.adjvex].data);
						EnQueue(Q,p->data.adjvex);
					}
			}
		} 
	}
	printf("\n\n");
}

//拓扑排序 
int indegree[MAX_VERTEX_NUM];
void FindInDegree(ALGraph G)
{
	int i;
	ArcNode *p;
	for(i=0;i<G.vexnum;++i)
		indegree[i]=0;
	for(i=0;i<G.vexnum;++i)
	{
		p=G.vertices[i].firstarc;
		while(p)
		{
			indegree[p->data.adjvex]++;
			p=p->nextarc;
		}
	}
}
status TopologicalSort(ALGraph G)
{
	int i,k,count=0;
	SqStack S;
	ArcNode *p;
	FindInDegree(G);
	InitStack(S);
	for(i=0;i<G.vexnum;++i)
		if(!indegree[i])
		Push(S,i);
	while(!StackEmpty(S))
	{
		Pop(S,i);
		Visit(G.vertices[i].data);
		++count;
		for(p=G.vertices[i].firstarc;p;p=p->nextarc)
		{
			k=p->data.adjvex;
			if(!(--indegree[k]))
				Push(S,k);
		}
	}
	if(count<G.vexnum)
	{
		printf("此图存在回路\n");
		return error;
	}
	else
	{
		printf("为一个拓扑序列。\n");
		return ok;
	}
}
int main()
{
	ALGraph g;
	CreateGraph(g);
	printf("深度优先搜索遍历的结果为:\n");
	DFSTraverse(g,Visit);
	printf("广度优先搜索遍历的结果为:\n");
	BFSTraverse(g,Visit);
	TopologicalSort(g);
	return 0;
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值