实验六 图的操作实现

一、实验目的

1、 理解图的存储结构与基本操作;

2、 掌握图的创建过程

 

二、实验内容

    1.根据下图,采用邻接矩阵的存储结构保存此图,并打印出邻接矩阵。

图的创建代码参考教材.

提示:首先根据给出的图结构得出该图的顶点集和边集,调用相应的函数生成图的邻接矩阵,并打印出邻接矩阵。

2.根据上一题的邻接矩阵,编程实现该图的深度与广度优先遍历算法,从顶点1开始遍历,分别输出深度与广度优先遍历序列。

3.选做题:单源最短路径问题

问题描述:求从有向图的某一结点出发到其余各结点的最短路径。

基本要求:

(1)有向图采用邻接矩阵表示。

(2)单源最短路径问题采用Dijkstra算法。

(3)输出有向图中从源结点A到其余各结点的最短路径和最短路径值。

三、【实验源代码】

 头文件
typedef struct
 {
 	int list[100];
 	int size;
 }SequenceList;
 
 
 int ListInitiate(SequenceList *L)
 {
 	L->size = 0;
 }
 
 
 int ListInsert(SequenceList *L,int i, char x)
 {
 	int j;
 	if(L->size >= 100)
 	{
 		printf("顺序表已满\n");
 		return 0;
 	}
 	else if (i<0 || i>L->size)
 	{
 		printf("不合法");
 		return 0;
 	}
 	else
 	{
 		for(j=L->size;j>i;j--)
 			L->list[j]=L->list[j-1];
 		L->list[i]=x;
 		L->size ++;
 		return 1;
 	}
 }
 int ListLength(SequenceList L)
 {
 	return L.size;
 }
 
 typedef struct
 {
 	SequenceList Vertices;
 	int edge[100][100];
 	int numOfEdges;
 }MatrixGraph;
 
 void Initiate(MatrixGraph *G,int n)
 {
 	int i,j;
 	for(i=0;i<n;i++)
 	{
 		for(j=0;j<n;j++)
 		{
 		 G->edge[i][j]=0;
 		
		}
	}
	G->numOfEdges=0;
	ListInitiate(&G->Vertices) ;
 }
 
 void InsertVertex(MatrixGraph *G,int vertex)
 {
 	ListInsert(&G->Vertices,G->Vertices.size,vertex);
 }
 
 void InsertEdge(MatrixGraph *G,int v1,int v2)
 {
 	if(v1<0||v1>=G->Vertices.size||v2<0||v2>=G->Vertices.size)
 	{
 		printf("参数错误");
		exit(1);
	 }
	 G->edge[v1][v2]=1;
	 G->edge[v2][v1]=1;
	 G->numOfEdges++;
 }
 
 typedef struct
 {
 	int row,col;
 }RowCol;
 
 void CreatGraph(MatrixGraph *G,int V[],int n,RowCol E[],int e)
 {
 	int i,k;
 	Initiate(G,n);
 	for(i=0;i<n;i++)
 		InsertVertex(G,V[i]);
 	for(k=0;k<e;k++)
 		InsertEdge(G,E[k].row,E[k].col);
 }
int visit_dfs[100];
void dfs(MatrixGraph G,int i)
{
	int j;
    visit_dfs[i]=1;
	printf("%c ",G.Vertices.list[i]);
	for(j=0;j<G.numOfEdges ;j++)
	{
		if(G.edge [i][j]==1&&!visit_dfs[j])
		dfs(G,j);
	}
}
void dfstraverse(MatrixGraph G)
{
	int i;
	for(i=0;i<G.numOfEdges ;i++)
	{
		visit_dfs[i]=0;
	}
	for(i=0;i<G.numOfEdges ;i++)
	{
		if(!visit_dfs[i])
		dfs(G,i);
	}
}
typedef struct Qnode
{
	int data;
	struct Qnode *next;
}Qnode, *Qptr;     //定义节点

typedef struct LINKQUEUE
{
	Qptr front;
	Qptr rear;
}LinkQueue;       //定义队首、队尾指针
void InitQueue(LinkQueue *q) //队列初始化
{
	//定义头结点,队首队尾都指向头结点
	Qptr firstnode = (Qptr)malloc(sizeof(Qnode));
	q->front = q->rear = firstnode;
	if (!q->front)
	{
		exit(0);
	}
	q->front->next = NULL;
}
void PushQueue(LinkQueue *q, int e) 
{
	//在队尾插入元素
	Qptr p = (Qptr)malloc(sizeof(Qnode));
	if (!p)
	{
		exit(0);
	}
	p->data = e;
	p->next = NULL;
	q->rear->next = p;
	q->rear = p;
}
void DetQueue(LinkQueue *q, int e)
{
	//出队列在队首进行
	if (q->front == q->rear)
	{
		printf("队列中无元素!\n");
		exit(0);
	}
	Qptr p = q->front->next;
	e = p->data;
	q->front->next = p->next;
	if (q->rear == p)
	{
		q->rear = q->front;
	}
	free(p);
}
//检验是否为空
int QueueEmpty(LinkQueue *q)
{
	if (q->front == q->rear)
		return 0;
	else
		return 1;
}
int visited[100];
void BFSTraverse(MatrixGraph G)
{
	int k;
	int i,j;
	LinkQueue Q;
	InitQueue(&Q);
	for (i = 0; i < G.numOfEdges ; i++)
	{
		visited[i] = 0; //初始化标记数组
	}
	for (i = 0; i < G.numOfEdges ; i++)
	{
		if (!visited[i])
		{
			visited[i] = 1;
			printf("%c ", G.Vertices .list[i]);
			PushQueue(&Q, i);
		}
		while (!QueueEmpty(&Q))
		{
			DetQueue(&Q, k);
			for ( j = 0; j < G.numOfEdges ; j++)
			{
				if (G.edge [k][j] == 1 && !visited[j])
				{
					visited[j] = 1;
					printf("%c", G.Vertices .list[j]);
					PushQueue(&Q, j);
				}
			}
		}
	}
}
主函数
#include<stdio.h>
#include<stdlib.h>
#include"MGraph.h"
void main()
 {
 	MatrixGraph g1;
 	int a[]={'1','2','3','4','5'};
 	RowCol rc[]={{0,1},{0,2},{0,3},{0,4},{1,3},{2,4}};
 	int n=5,e=6;
 	int i,j;
 	CreatGraph(&g1,a,n,rc,e);
 	printf("顶点集合为:\n");
 	for(i=0;i<g1.Vertices.size;i++)
 	printf("%c ",g1.Vertices.list[i]);
 	printf("\n");
 	printf("邻接矩阵为:\n");
 	for(i=0;i<g1.Vertices.size;i++)
 	printf("%5c",g1.Vertices.list[i]);
 	printf("\n\n");
 	for(i=0;i<g1.Vertices.size;i++)
 	{
 		printf("%d",i+1);
 		for(j=0;j<g1.Vertices.size;j++)
 		printf("%5d",g1.edge[i][j]);
 		printf("\n");
 	}
 	printf("深度优先遍历:\n");
 	dfstraverse(g1);
 	printf("\n广度优先遍历:\n");
	BFSTraverse(g1);

}
选做题
头文件
typedef struct
 {
 	int list[100];
 	int size;
 }SequenceList;
 
 
 int ListInitiate(SequenceList *L)
 {
 	L->size = 0;
 }
 
 
 int ListInsert(SequenceList *L,int i, char x)
 {
 	int j;
 	if(L->size >= 100)
 	{
 		printf("顺序表已满\n");
 		return 0;
 	}
 	else if (i<0 || i>L->size)
 	{
 		printf("不合法");
 		return 0;
 	}
 	else
 	{
 		for(j=L->size;j>i;j--)
 			L->list[j]=L->list[j-1];
 		L->list[i]=x;
 		L->size ++;
 		return 1;
 	}
 }
 int ListLength(SequenceList L)
 {
 	return L.size;
 }
 
 typedef struct
 {
 	SequenceList Vertices;
 	int edge[100][100];
 	int numOfEdges;
 }MatrixGraph;
 void Initiate(MatrixGraph *G,int n)
 {
 	int i,j;
 	for(i=0;i<n;i++)
 	{
 		for(j=0;j<n;j++)
 		{
 			if(i==j)
 		    G->edge[i][j]=0;
 		    else
 		    G->edge [i][j]=666;
		}
	}
	G->numOfEdges=0;
	ListInitiate(&G->Vertices) ;
 }
 void InsertVertex(MatrixGraph *G,int vertex)
 {
 	ListInsert(&G->Vertices,G->Vertices.size,vertex);
 }
 
 void InsertEdge(MatrixGraph *G,int v1,int v2,int w)
 {
 	if(v1<0||v1>=G->Vertices.size||v2<0||v2>=G->Vertices.size)
 	{
 		printf("参数错误");
		exit(1);
	 }
	 G->edge[v1][v2]=w;
	 G->numOfEdges++;
 }
 typedef struct
 {
 	int row,col,w;
 }RowCol;
 
 void CreatGraph(MatrixGraph *G,int V[],int n,RowCol E[],int e)
 {
 	int i,k;
 	Initiate(G,n);
 	for(i=0;i<n;i++)
 		InsertVertex(G,V[i]);
 	for(k=0;k<e;k++)
 		InsertEdge(G,E[k].row,E[k].col,E[k].w);
 }
主函数
#include<stdio.h>
#include<stdlib.h>
#include"mmm.h"
 void dijkstra(MatrixGraph G,int V0,int *sn,int *sw)
{
	int v,w,k,min;
	int final[G.Vertices.size];//标志数组,若顶点Vi最短路径已知,则final[i]=1;
	for(v=0;v<G.Vertices.size;v++){
		final[v]=0;
		sn[v]=0;
		sw[v]=G.edge[V0][v];
	}
	sw[V0]=0;
	final[V0]=1;
	//初始化完成,主循环开始
	for(v=1;v<G.Vertices.size;v++)
	{   //每次循环确定V0到一个顶点的最短路径 
		min=666;  //初始化最小值min 
		for(w=0;w<G.Vertices.size;w++)
		{    //遍历寻找离V0最近的点
			if(!final[w]&&sw[w]<min)
			{   //如果Vw的最短路径还没找到且w到V0的权值比min小 
				k=w;    //k存储离V0最近的点的下边 
				min=sw[w];
			 //那么顶点Vw离V0更近 
			} 
		} 
		final[k]=1;  //Vk是离V0最近的点,则Vk的最短路径已经找到,所以标志改为1 
	    for(w=0;w<G.Vertices.size;w++){
	    	if(!final[w]&&(min+G.edge[k][w])<sw[w]){  
//如果顶点Vw的最短路径未确定且经过VK的路径比V0直达的路径短的话 
	    		sw[w]=min+G.edge[k][w];
	    		sn[w]=k;  //经过Vk的路径更短,则其前驱下标为k 
			}
		} 
	} 
	sn[0]=-1;
}
void prin(int n ,int *sn)
{
	int a[10]={0},i=1,j=n,q=0;
	a[0]=n;
	while(1)
	{
		if(sn[j]==-1)
		break;
		a[i]=sn[j];
		j=a[i];
		i++;
	}
	q=i;
	for(i=q-1;i>-1;i--)
	printf("%c ",a[i]+65);
	
}
void main()
{
	MatrixGraph g1;
 	int a[]={'A','B','C','D','E','F'};
 	RowCol rc[]={{0,2,5},{0,3,30},{1,0,2},{1,4,8},{2,1,15},{2,5,7},{4,3,4},{5,3,10},{5,4,18}};
 	int n=6,e=9;
 	int i,j;
 	CreatGraph(&g1,a,n,rc,e);
 	printf("顶点集合为:\n");
 	for(i=0;i<g1.Vertices.size;i++)
 	printf("%c ",g1.Vertices.list[i]);
 	printf("\n");
 	printf("邻接矩阵为:\n");
 	for(i=0;i<g1.Vertices.size;i++)
 	printf("%5c",g1.Vertices.list[i]);
 	printf("\n\n");
 	for(i=0;i<g1.Vertices.size;i++)
 	{
 		printf("%c",65+i);
 		for(j=0;j<g1.Vertices.size;j++)
 		printf("%5d",g1.edge[i][j]);
 		printf("\n");
 	}
 	int sn[100],v0=0;
 	int sw[100];
 	dijkstra(g1,v0,sn,sw);
    printf("从顶点A到其他各项顶点的最短距离为:\n");
 	for(i=0;i<g1.Vertices.size;i++)
 		printf("到顶点%c的最短距离为%d\n",65+i,sw[i]);	
 	printf("path数组:\n");	
 	for(i=0;i<g1.Vertices.size;i++)
 	    printf("%d  ",sn[i]);
 	printf("\n");
 	printf("A到其他点的最短路:\n");
 	for(i=1;i<g1.Vertices.size;i++)
 	{
 		prin(i,sn);
 		printf("\n");
 	 }	
}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

跳舞的muse

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值