数据结构——图的操作算法(一)

一、实验目的及要求

1.熟悉各种图的存储结构(邻接矩阵和邻接表)。
2.掌握图的深度优先和广度优先遍历算法。
3.掌握克鲁斯卡尔算法生成最小生成树的方法。
4.掌握狄克斯特拉算法计算最短路径和最短路径长度的方法。

二、实验内容(或实验原理、实验拓扑)

1.假设下图不带权有向图采用邻接矩阵g存储,设计实现以下功能的算法:
(1)输出有向图的邻接矩阵。
(2)求出图中每个顶点的入度。
(3)求出图中每个顶点的出度。
(4)求出图中出度为0的顶点

三、实验设计方案(包括实验步骤、设计思想、算法描述或开发流程等)

(一)在graph.h中创建图的两种存储结构:
1.首先定义邻接矩阵的定点类型VertexType;
2.然后定义完整的图邻接矩阵类型MatGraph。
(二)在main.cpp中完成图的基本运算算法:
1. 创建图的邻接矩阵CreateMat(MatGraph &g,int A[MAXV][MAXV],int n,int e);
2. 输出邻接矩阵gDispMat(MatGraph g);
3. 求图G中每个顶点的入度InDs1(MatGraph g);
4. 求出图G中每个顶点的出度以及出度为零的顶点OutDs1(MatGraph g);
5.主函数 main()根据问题依次调用基本操作函数并编写通俗易懂的语句输出。

四、实验结果(包括设计效果、测试数据、运行结果等)

运行结果如下:

五、实验小结(包括收获、心得体会、注意事项、存在问题及解决办法、建议等)

首先邻接矩阵是表示顶点之间相邻关系的矩阵。设G=(V,E)是具有n(n>0)个顶点的图,顶点的顺序依次为0~n-1,则G的邻接矩阵A是n阶方阵。其次对于有向图,邻接矩阵的第i行(或第i列)非零元素(或非∞元素)的个数正好是第i个顶点的出度(或入度)。用邻接矩阵方法存储图,很容易确定图中任意两个顶点之间是否有边相连。但是,要确定图中有多少条边,则必须按行、按列对每个元素进行检测,所花费的时间代价很大。另外图的邻接矩阵表示是唯一的,邻接矩阵适合于存储边的数目较多的稠密图。

六、附录(包括作品、流程图、源程序及命令清单等)

graph.h:
//图的两种存储结构
#define INF 32767				//定义∞
#define	MAXV 100				//最大顶点个数
typedef char InfoType;
//以下定义邻接矩阵类型
typedef struct
{	int no;						//顶点编号
	InfoType info;				//顶点其他信息
} VertexType;					//顶点类型
typedef struct
{	int edges[MAXV][MAXV];		//邻接矩阵数组
	int n,e;					//顶点数,边数
	VertexType vexs[MAXV];		//存放顶点信息
} MatGraph;						//完整的图邻接矩阵类型 

图的基本运算算法:
#include <stdio.h>
#include <malloc.h>
#include "graph.h"
void CreateMat(MatGraph &g,int A[MAXV][MAXV],int n,int e) //创建图的邻接矩阵
{
	int i,j;
	g.n=n; g.e=e;
	for (i=0;i<g.n;i++)
		for (j=0;j<g.n;j++)
			g.edges[i][j]=A[i][j];
}
void DispMat(MatGraph g)	//输出邻接矩阵g
{
	int i,j;
	for (i=0;i<g.n;i++)
	{
		for (j=0;j<g.n;j++)
			if (g.edges[i][j]!=INF)
				printf("%4d",g.edges[i][j]);
			else
				printf("%4s","∞");
		printf("\n");
	}
}
void InDs1(MatGraph g)   //求出图G中每个顶点的入度
{
  int i,j,n;
  printf("各顶点的入度:\n");
  for(j=0;j<g.n;j++)
    {
      n=0;
      for(i=0;i<g.n;i++)
         if(g.edges[i][j]!=0)
               n++;            //n累计入度数
      printf(" 顶点%d:%d\n",j,n);
     }
}
void OutDs1(MatGraph g)   //求出图G中每个顶点的出度
{
  int i,j,n;
  printf("各顶点的出度:\n");
  for(i=0;i<g.n;i++)
    {
      n=0;
      for(j=0;j<g.n;j++)
         if(g.edges[i][j]!=0)
               n++;            //n累计出度数
      printf(" 顶点%d:%d\n",i,n);
     }
     printf("出度为零的顶点:\n");
     for(i=0;i<g.n;i++)
    {
      n=0;
      for(j=0;j<g.n;j++)
         if(g.edges[i][j]!=0)
               n++;
      if(n==0)
      printf("%d\n",i);
     }
}
int main()
{
	MatGraph g;
	int A[MAXV][MAXV]={{0,1,0,1,0},{0,0,1,1,0},
			{0,0,0,1,1},{0,0,0,0,0},{1,0,0,1,0}};
	int n=5, e=8;
	CreateMat(g,A,n,e);			//建立邻接矩阵
	printf("图G的邻接矩阵:\n");
	DispMat(g);					//输出邻接矩阵g
	InDs1(g);
	OutDs1(g);
	return 1;
}
  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值