【数据结构 图】数据结构实验--图及其应用

数据结构实验–图及其应用

(代码有一些纰漏 仅供自己后期修改保存用)

数据结构上机实验

题目:设计并验证如下算法:

带权图采用邻接表表示,实现无向图的广度优先搜索BFS与有向图的深度优先搜索DFS。
#define MAX_VERTEX_NUM 20	//图的邻接表存储表示
typedef struct ArcNode{
int adjvex; 	//该弧所指向的顶点的位置
struct ArcNode *nextarc; 	//指向下一条弧的指针
InfoType *info; 	//该弧相关信息的指针
}ArcNode;

typedef struct VNode {
VertexType data; 	//顶点信息
ArcNode *firstarc; 	//指向第一条依附该顶点弧的指针
}VNode,AdjList[MAX_VERTEX_NUM]

Typedef struct {
AdjList vertices;
int vexnum,arcnum; 	//图的当前顶点数和弧数
int kind; 	//图的种类标志
}ALGraph;

实现代码如下

//Queue.h头文件

#define	QUEUE_INIT_SIZE	100
#define	QUEUE_INCREASE_SIZE 10
#define OK		1
#define ERROR	0
#define TRUE	1
#define FALSE	0
#define	OVERFLOW 0

typedef struct 	SqQueue{
	QElemType *base; //空间基指针 
	int front;//队头元素数组下标 
	int tail;//队尾元素数组下标	
}*Queue;

Status	InitQueue(Queue);			//初始化结构体指针S 返回一个空队列 Q
Status	DestroyQueue(Queue );	//销毁非空队列 Q
Status	ClearQueue(Queue );		//把非空队列 Q置为空队列 
Status	QueueEmpty(SqQueue Q);			//判断Q是否为空队列 
Status	FullQueue(SqQueue ) ;			//判断是否是满队列 
Status	QueueLength(SqQueue , int *) ;			//返回队列Q的元素个数
Status	DeQueue(Queue , QElemType *);	//删除Q中队首元素 
Status	EnQueue(Queue , QElemType );	//队尾 将元素E排入队Q中   
Status	QueueTraverse(SqQueue );				//从队首到队尾依次输出队列中每个元素

Status	InitQueue(Queue Q){		//初始化结构体指针Q 返回一个空队列Q 
		Q->base = (QElemType *)malloc( sizeof(QElemType )* QUEUE_INIT_SIZE  );
		if(!Q->base ) exit(OVERFLOW);
		Q->front = Q->tail = 0; 
		return OK;
}

Status	DestroyQueue(Queue Q){	//销毁非空队列Q
		free(Q->base);
		Q->base = NULL;
		return OK;
}

Status	ClearQueue(Queue Q){		//把非空队列 Q置为空队列	
		while(Q->front != Q->tail)
		Q->front = (Q->front+1)%QUEUE_INIT_SIZE; 
		return OK;
}

Status	QueueEmpty(SqQueue Q){			
		if(Q.front == Q.tail ) return TRUE;
		else return FALSE;		
}

Status	FullQueue(SqQueue Q){
	if( Q.front == (Q.tail + 1) % QUEUE_INIT_SIZE )
	return TRUE;
	else return FALSE;
}

Status	QueueLength(SqQueue Q, int *length){
	*length = 0;//设置为0 
	while(Q.base[Q.front] != Q.base[Q.tail] ) {
		Q.front = (Q.front + 1)% QUEUE_INIT_SIZE;
		(*length) ++;
	}
	return OK; 
}

Status	EnQueue(Queue Q, QElemType e){ 
		if( (Q->tail+1)%QUEUE_INIT_SIZE ==Q->front)return ERROR;//队列满 
		Q->base[Q->tail ] = e;
		Q->tail =(Q->tail+1)%QUEUE_INIT_SIZE;
		return OK;
}	

Status	DeQueue(Queue Q, QElemType *e){
	if(QueueEmpty(*Q) ) return ERROR;
	else{
		*e = Q->base[Q->front];
		Q->front = (Q->front + 1)% QUEUE_INIT_SIZE;
		return OK;	
	}		
}

Status	QueueTraverse(SqQueue Q){
	if(Q.front == Q.tail){
		printf("Empty Queue");
		return ERROR;
	}//队列空
	
	while(Q.front!= Q.tail ){
	printf("%5d",Q.base[Q.front]) ;
	Q.front = (Q.front+1)% QUEUE_INIT_SIZE;	
	}
	
	return OK;
}

Graph.h头文件(为方便起见将Graph.cpp文件写在.h文件中)

#ifndef STDIO_H
#define STDIO_H
#include "stdio.h"
#endif

#ifndef STDLIB_H
#define STDLIB_H
#include "stdlib.h"
#endif

#ifndef QUEUE_H
#define QUEUE_H
typedef int QElemType;
#include "Queue.h" 

#endif

#ifndef GRAPH_STRUCT_H
#define GRAPH_STRUCT_H
#define MAX_VERTEX_NUM 20	//图的邻接表存储表示
//弧 
typedef struct ArcNode{
	int adjvex;	//该弧所指向的顶点的位置(数组下标) 
	struct ArcNode *nextarc;	//指向下一条弧的指针
	InfoType info; 	//权重 
}ArcNode;

//顶点 
typedef struct VNode {
	VertexType data; 	//顶点信息
	ArcNode *firstarc; 	//指向第一条依附该顶点的弧 的指针(对有向图而言 是以该顶点为尾的弧) 
}AdjList[MAX_VERTEX_NUM];

//总图 
typedef struct ALGraph{
	AdjList vertices;
	int vexnum;	//图的当前顶点数
	int arcnum; 	//图的当前弧数
	int kind; 	//图标志
}ALGraph;
#endif

#define	TRUE		1
#define	FALSE		0
#define ERROR 		0
#define	OVERFLOW 	0	

/*基本操作*/ 
void 	CreateGraph(ALGraph *G);//创建图 其中V是图的顶点集 VR是顶点间的关系 
void 	DestroyGraph(ALGraph *G);	//销毁图G
int		LocateVex(ALGraph G,VNode u);	//G中存在顶点u则返回其在图中位置 否则返回其他信息
int		FirstAdjVex(ALGraph G, int v,ArcNode **w) ;//返回顶点v的第一个邻接顶点 若无临接顶点 则返回"空"  
int		NextAdjVex(ALGraph G, int v, ArcNode **p);//返回v相对于w的下一个邻接顶点 若是w已经是最后一个邻接顶点 则返回"空" 
void	DFSTraverse(ALGraph G);		//深度优先遍历图 
void	DFS(ALGraph G,int v, int *visited);
void	BFSTraverse(ALGraph G);		//广度优先遍历图 
/*各基本操作实现*/

/*图创建*/ 
void	CreateGraph(ALGraph *G){
	int i,  k, v, w;
	ArcNode *p=NULL, *q = NULL;
	printf("\n依次输入图的结点个数,边的个数:");
	scanf("%d%d",& G->vexnum, & G->arcnum);
	for(i = 1; i<=G->vexnum; i++){//创建顶点 
		printf("\n请输入%d号顶点信息:",i);
		rewind(stdin);
		scanf("%c",& G->vertices[i].data);
		G->vertices[i].firstarc = NULL;
	}
	for(k=1; k<=G->arcnum; k++){
		p = (ArcNode*)malloc(sizeof(ArcNode));
		scanf("%d%d", &v, &w);
		p->adjvex = w;
		scanf("%d", & p->info);
		p->nextarc = NULL;
		q = G->vertices[v].firstarc;
		G->vertices[v].firstarc = p;
		p->nextarc = q;//头插法 
	}//for 
	G->kind = 0;//默认 
}//CreateGraph()
 
/*图销毁*/ 
void	DestroyGraph(ALGraph *G){
	int i; 
	ArcNode *p= NULL, *q = NULL;
	//释放所有边结点 
	for(i =1 ; i<=G->vexnum; i++){
		while( G->vertices[i].firstarc){
			p = G->vertices[i].firstarc;
			q = p->nextarc;
			free(p);
			G->vertices[i].firstarc = q;
		}//释放一个结点发出的所有边 
	}//for 
	G->arcnum = 0;
	G->vexnum = 0;
}
/*图的遍历DFS(递归)*/
void	DFSTraverse(ALGraph G){
	int v;
	int visited[MAX_VERTEX_NUM]={0};
	for(v=1; v<=G.vexnum; v++){
		if(!visited[v]) DFS(G, v, visited);//对未访问的顶点调用DFS 
	}
}
void	DFS(ALGraph G,int v, int *visited){
	int w;
	ArcNode *p=NULL; 
	visited[v] = 1;
	printf(" %c ",G.vertices[v].data);
	for(w = FirstAdjVex(G,v,&p); w>0; w=NextAdjVex(G, v, &p))
	if(!visited[w]) DFS(G, w, visited);
}


/*图的遍历BFS*/
void	BFSTraverse(ALGraph G){
	int visited[MAX_VERTEX_NUM] = {0};
	int v, w, u;
	SqQueue Q;
	ArcNode *p =NULL; 
	InitQueue(&Q);	
	for(v = 1; v<=G.vexnum; v++ ){
		if(!visited[v]){
			visited[v] = 1;//标志已访问过 
			printf(" %c ",G.vertices[v].data);
			EnQueue(&Q, v);
			while(!QueueEmpty(Q)){
				DeQueue(&Q, &u);
				for(w=FirstAdjVex(G, u, &p); w>0; w = NextAdjVex(G, u ,  &p) ){
					if(!visited[w]){
						visited[w] = 1;
						printf(" %c ",G.vertices[w].data);
						EnQueue(&Q, w);
					} 
				}//for
			}//while		
		}//if		
	}//for	
}//BFSTraverse()

int	LocateVex(ALGraph G,VNode u){
	int i = 1;
	for(i =G.vexnum ; i ; i--){
		if(G.vertices[i].data == u.data)
		break;
	}
	return i; //若为0则没找到		
}

int	FirstAdjVex(ALGraph G, int v,ArcNode **w){
	if (!(*w=G.vertices[v].firstarc ) ) return 0;
	return	(*w)->adjvex;
}

int	NextAdjVex(ALGraph G, int v,ArcNode **p)//返回v相对于w的下一个邻接顶点 若是w已经是最后一个邻接顶点 则返回"空" 
{
	if(!(*p)->nextarc)	return 0;
	int t=(*p)->nextarc->adjvex;
	*p=(*p)->nextarc;
	return t;
}

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值