#include <stdio.h>
#include <stdlib.h>
#define MAX_VERTEX_NUM 20 //图的最大顶点数
#define MAXQSIZE 30       //队列的最大容量 
#define INFINITY 32768             /*表示极大值,即∞*/
#define TRUE       1
#define FALSE      0
#define ERROR -1
#define OK 1

typedef int QueueElementType;
typedef struct Node
{
	QueueElementType data;     /*数据域*/
	struct Node *next;     /*指针域*/
}LinkQueueNode;

typedef struct 
{
	LinkQueueNode *front;
	LinkQueueNode *rear;
}LinkQueue;

/*初始化操作。*/
int InitQueue(LinkQueue *Q)
{ 
	/* 将Q初始化为一个空的链队列 */
	Q->front=(LinkQueueNode *)malloc(sizeof(LinkQueueNode));
	if(Q->front!=NULL)
	{
		Q->rear=Q->front;
		Q->front->next=NULL;
 		return(TRUE);
	}
	else return(FALSE);    /* 溢出!*/
}

/*入队操作。*/
int EnterQueue(LinkQueue *Q,QueueElementType x)
{  
	/* 将数据元素x插入到队列Q中 */
	LinkQueueNode *NewNode;
	NewNode=(LinkQueueNode * )malloc(sizeof(LinkQueueNode));
	if(NewNode!=NULL)
	{
		NewNode->data=x;
		NewNode->next=NULL;
		Q->rear->next=NewNode;
		Q->rear=NewNode;
		return(TRUE);
	}
	else  return(FALSE);    /* 溢出!*/
}

/*出队操作。*/
int DeleteQueue(LinkQueue *Q,QueueElementType *x)
{  
	/* 将队列Q的队头元素出队,并存放到x所指的存储空间中 */
	LinkQueueNode * p;
	if(Q->front==Q->rear)
		return(FALSE);
	p=Q->front->next;
	Q->front->next=p->next;  /* 队头元素p出队 */
	if(Q->rear==p)  /* 如果队中只有一个元素p,则p出队后成为空队 */
		Q->rear=Q->front;  
	*x=p->data;
	free(p);   /* 释放存储空间 */
	return(TRUE);	
}

int IsEmpty(LinkQueue *Q)
{
	if(Q->front==Q->rear)
		return(TRUE);
	else 
		return(FALSE);
}

#define ElemType char
#define	MAXSIZE  100   /*此处的宏定义常量表示线性表可能达到的最大长度*/
typedef  struct
{ 
	ElemType  elem[MAXSIZE];  /*线性表占用的数组空间*/
	int       last;    /*记录线性表中最后一个元素在数组elem[ ]中的位置(下标值),空表置为-1*/
}SeqList;

void InitList(SeqList *L)
{
	L->last=-1;
}

int AddTail(SeqList *L, ElemType e)
{
	if(L->last>=MAXSIZE-1)
	{
		printf("表已满,无法添加!");
		return ERROR;
	}
	L->elem[++L->last]=e;
	return OK;
}



typedef enum{DG, DN, UDG, UDN} GraphKind;  /*图的种类:DG表示有向图, DN表示有向网, UDG表示无向图, UDN表示无向网*/
typedef char VertexData;    /*假设顶点数据为字符型*/

typedef struct ArcNode
{
	int adj;/*对于无权图,用1或0表示是否相邻;对带权图,则为权值类型*/

} ArcNode;

typedef struct
{
	VertexData verxs[MAX_VERTEX_NUM];                        /*顶点向量*/
	ArcNode arcs[MAX_VERTEX_NUM][MAX_VERTEX_NUM];   /*邻接矩阵*/
	int vexnum,arcnum;          /*图的顶点数和弧数*/
	GraphKind kind;                 /*图的种类标志*/
}AdjMatrix;      /*(Adjacency Matrix Graph)*/

int LocateVertex(AdjMatrix *G,VertexData v)    /*求顶点位置函数*/
{
	int j=ERROR,k;
	for(k=0;k<G->vexnum;k++)
		if(G->verxs[k]==v)
		{ 
			j=k; 
			break; 
		}
	return(j);
}

int CreateDN(AdjMatrix *G)  /*创建一个有向网*/
{ 
	int i,j,k,weight; 
	VertexData v1,v2;
	printf("输入图的类型:0-有向图,1-有向网,2-无向图,3-无向网\n");
	scanf("%d,%d",&G->arcnum,&G->vexnum);
	for(i=0;i<G->vexnum;i++)
        for(j=0;j<G->vexnum;j++)
			G->arcs[i][j].adj=INFINITY;
		for(i=0;i<G->vexnum;i++)
			scanf("%c",&G->verxs[i]);
		for(k=0;k<G->arcnum;k++)
		{   scanf("%c,%c,%d",&v1,&v2,&weight);
		    i=LocateVertex(G,v1);
			j=LocateVertex(G,v2);
			G->arcs[i][j].adj=weight;
	//请编程实现此函数功能;
	} 
	return(OK);
}
int visit(int v0)
{
	printf("%d",v0);
	return(OK);
}
int visited[MAX_VERTEX_NUM];  /*访问标志数组*/
/*用邻接矩阵方式实现深度优先搜索*/
void DepthFirstSearch(AdjMatrix g,int v0) /* 图g 为邻接矩阵类型AdjMatrix */ 
{   
   int vj;
	visit(v0);visited[v0]=TRUE;
	for(vj=0;vj<g.vexnum;vj++)
		if(!visited[vj]&&g.arcs[v0][vj].adj==1)
			DepthFirstSearch(g,vj);
	//请编程实现此函数功能
}/* DepthFirstSearch */

/*用邻接矩阵方式实现广度优先搜索*/
void BreadthFirstSearch(AdjMatrix g,int v0)
{   
	int vj;
	visit(v0);visited[v0]=TRUE;
	for(vj=0;vj<g.vexnum;vj++)
		if(g.arcs[v0][vj].adj==1)
			BreadthFirstSearch(g,vj);
	//请编程实现此函数功能;
}
void TraverseGraph1(AdjMatrix g)
/*对图g进行深度优先搜索*/
{
	int vi;
	for(vi=0;vi<g.vexnum;vi++)  
		visited[vi]=FALSE ;/*访问标志数组初始*/
	for(vi=0;vi<g.vexnum;vi++)	/*调用深度遍历连通子图的操作*/
		if (!visited[vi]) 
		     DepthFirstSearch(g,vi);	/*若图g是连通图,则此循环调用函数只执行一次*/
}/* TraverseGraph */

void TraverseGraph2(AdjMatrix g)
/*对图g进行广度优先搜索*/
{
	int vi;
	for(vi=0;vi<g.vexnum;vi++)  
		visited[vi]=FALSE ;/*访问标志数组初始*/
	for(vi=0;vi<g.vexnum;vi++)	/*调用深度遍历连通子图的操作*/
		if (!visited[vi])  
		     DepthFirstSearch(g,vi);	/*若图g是连通图,则此循环调用函数只执行一次*/
}/* TraverseGraph */

#define INFINITY 32768
typedef unsigned int WeightType;
typedef SeqList VertexSet;

int Member(VertexData v, VertexSet s)
{
	int i;
	for(i=0;i<=s.last;i++)
		if(s.elem[i]==v)
			return TRUE;
	return FALSE;
}

void ShortestPath_DJS(AdjMatrix g,int v0,WeightType dist[MAX_VERTEX_NUM],VertexSet path[MAX_VERTEX_NUM])
/* path[i]中存放顶点i的当前最短路径。dist[i]中存放顶点i的当前最短路径长度*/
{ 
	int i,t,k;
	unsigned int min;
	VertexSet s;
	for(i=0;i<g.vexnum;i++)
	{ InitList(&path[i]);
	  dist[i]=g.arcs[v0][i].adj;
	  if(dist[i]<INFINITY)
	  { AddTail(&path[i],g.verxs[v0]);
	    AddTail(&path[i],g.verxs[i]);
	  }
	}
	InitList(&s);
	AddTail(&s,g.verxs[v0]);
	for(t=1;t<=g.vexnum;i++)
		if(!Member(g.verxs[i],s)&&dist[i]<min)
		{ k=i;min=dist[i];}
		if(min==INFINITY) return;
		AddTail(&s,g.verxs[k]);
		for(i=0;i<g.vexnum;i++)
			if(!Member(g.verxs[i],s)&&g.arcs[k][i].adj!=INFINITY&&(dist[k]+g.arcs[k][i].adj<dist[i]))
			{
				dist[i]=dist[k]+g.arcs[k][i].adj;
				path[i]=path[k];
				AddTail(&path[i],g.verxs[i]);
			}
	//请编程实现此函数功能;
}

void print(AdjMatrix G,VertexSet s[])
{
	int i,j;
	for(i=0;i<G.vexnum;i++)
	{
		if(s[i].last==-1)
			printf("到%c点没有路径。\n",G.verxs[i]);
		else
		{
			for(j=0;j<=s[i].last;j++)
				printf("%c->",s[i].elem[j]);
			printf("\b\b  \n");
		}
	}
}

int main()
{
	AdjMatrix G;  //采用邻接表结构的图
	char sp;
	int choice,flag=1,v0;
	WeightType dist[MAX_VERTEX_NUM];
	VertexSet path[MAX_VERTEX_NUM];

	printf("本程序实现图的操作:\n");
	printf("可以进行创建图, 深度优先、广度优先操作,实现最短路径查找等的应用。\n");

	while(flag)
	{
		printf("请选择: \n");
		printf("1.创建图\n");
		printf("2.深度优先遍历\n");
		printf("3.广度优先遍历\n");
		printf("4.最短路径查找\n");
		printf("5.退出程序\n");
		scanf("%d",&choice);
		switch(choice)
		{
			case 1:
				CreateDN(&G);
				break;
			case 2:
				if(G.kind==DN||G.kind==UDN)
					printf("此为加权网!不适合遍历。\n");
				else
				{
					TraverseGraph1(G);
					printf("\b\b  \n");
				}
				break;
			case 3:
				if(G.kind==DN||G.kind==UDN)
					printf("此为加权网!不适合遍历。\n");
				else
				{
					TraverseGraph2(G);
					printf("\b\b  \n");
				}
				break;
			case 4:
				printf("输入源点:\n");
				fflush(stdin);
				scanf("%c",&sp);
				v0=LocateVertex(&G,sp);
				ShortestPath_DJS(G,v0,dist,path);
				print(G,path);
				break;
			default:
				flag=0;
				printf("程序结束,按任意键退出!\n");
		}
	}
}

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值