图的存储及基本操作

实验题目: 图的存储及基本操作

一、实验目的
1、掌握图的顺序存储(邻接矩阵)存储实现;
2、掌握图的顺序存储(邻接矩阵)存储体上的基本操作;
3、掌握图的邻接链表存储实现;
4、掌握图的邻接链表存储体上的基本操作;
二、实验作业
在给出部分代码的基础上完成:
1、编写图的顺序存储(邻接矩阵)的函数,实现图的顺序存储(邻接矩阵)。
2、编写函数,在图的顺序存储体上进行:
(1)某顶点的度(出度,入度)的计算;
(2)输出某顶点的邻接点(邻接到的点)。
3、编写图的邻接链表函数,实现图的邻接链表存储。
4、编写函数,在图的邻接链表存储体上进行:
(1) 某顶点的度(出度,入度)的计算;
(2) 输出某顶点的邻接点(邻接到的点)。

三、实验内容
1、

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#define MAXN 105
#define RST(N) memset(N, 0, sizeof(N))  //宏定义函数RST(N):使数组N清零
//memset()一般是对字符型数组赋初值,如果非要对整型数组赋初值,只能赋值0.
//原因是memset是设置每一个“字节”的值。
using namespace std;
 
int n, m, Edge[MAXN][MAXN];  //顶点数,有向边数,邻接矩阵;
int Mc, Md, u, v;  //入度,出度,边的起点,终点;
 
void Init()  //初始化;
{
	RST(Edge);  //二维数组Edge清零
	for(int i=1; i<=m; i++) {  //添加有向边
		scanf("%d %d", &u, &v);
		Edge[u-1][v-1] = 1;
		printf("The %d edge is %d->%d,\n", i,u,v);
	}
}
 
void Print_In_Degree()  //输出有向图各顶点的入度;
{
	printf("The degree of entry of each vertex of the digraph is: ");
	for(int i=0; i<n; i++) {
		Mc = 0;
		for(int j=0; j<n; j++) Mc += Edge[i][j];
		printf("%d", Mc);
		i == n-1 ? printf("\n") : printf(" ");
	}
}
 
void Print_Out_Degree()  //输出有向边各顶点的出度;
{
	printf("The degree of leaving of each vertex of the digraph is: ");
	for(int i=0; i<n; i++) {
		Md = 0;
		for(int j=0; j<n; j++) Md += Edge[j][i];
		printf("%d", Md);
		i == n-1 ? printf("\n") : printf(" ");
	}
}
 
int main()
{
	freopen("实验6.1_data_in.txt", "r", stdin);
//	freopen("实验6.1_data.out", "w", stdout);
//	scanf("%d %d", &n, &m); 
//	Init();
	while(~scanf("%d %d", &n, &m)) {     // && n || m 
		printf("This Graph has %d nodes, and %d edges\n", n,m);
		Init();   //从文件中读入所有的边,构造邻接矩阵
		Print_In_Degree(), Print_Out_Degree();
	}
	fclose(stdin);
//	fclose(stdout);
	return 0;
}

2、

#include <iostream>
#include <stdio.h>
#include <string.h>
#define MAX 1000
int array [MAX][MAX];
using namespace std;
int main(int argc, char *argv[]) {	
	int i,j;             //循环变量
	int verNum,edgeNum;  //顶点数和边数
	int verArray [1000][100];
	int on,in;           //出度和入度
	int start , end;     //起点,终点
	while(1){
		freopen("实验6.1_data_in.txt", "r", stdin);
		memset(array,0,sizeof(array));   //数组初始化  函数头文件   <memory.h> or <string.h>
		scanf("%d%d", &verNum, &edgeNum);
		if(verNum == 0 && edgeNum == 0){
			break ;
		}
		for(i = 0 ;i < edgeNum;i ++){
			scanf("%d%d", &start, &end);
            array[start - 1][end  - 1] = 1;
		}
		for(i =0 ; i < verNum; i++){
			on = 0;   //按行数,表示顶点的出度
			for(j = 0 ;j < verNum;j++){
				if(array[i][j] == 1){
					on++;
				}
			}
			if(i == 0){
				printf("%d",on);   //注意输出格式判断
			}else{
				printf(" %d",on);
			}
		}
		printf("\n");     //换行
		for(i = 0 ; i < verNum; i++){
			in = 0;   //按行数,表示顶点的出度
			for(j = 0 ;j < verNum;j++){
				if(array[j][i] == 1){
					in++;
				}
			}
			if(i ==0 ){
				printf("%d",in);
			}else{
				printf(" %d",in);   //没有初始化时,会输出48706等奇怪数字
			}	
		}
		break;
	}
	return 0;
}
typedef int ElemType;
typedef struct 
{	
	ElemType data[MaxSize];
	int front,rear;		//队首和队尾指针
} SqQueue;
void InitQueue(SqQueue *&q)
{	q=(SqQueue *)malloc (sizeof(SqQueue));
	q->front=q->rear=0;
}
void DestroyQueue(SqQueue *&q)
{
	free(q);
}
bool QueueEmpty(SqQueue *q)
{
	return(q->front==q->rear);
}
bool enQueue(SqQueue *&q,ElemType e)
{	if ((q->rear+1)%MaxSize==q->front)	//队满上溢出
		return false;
	q->rear=(q->rear+1)%MaxSize;
	q->data[q->rear]=e;
	return true;
}
bool deQueue(SqQueue *&q,ElemType &e)
{	if (q->front==q->rear)				//队空下溢出
		return false;
	q->front=(q->front+1)%MaxSize;
	e=q->data[q->front];
	return true;
}
//---------------------------------------------------------

void BFS(AdjGraph *G,int v)  
{
	int w,i;
	ArcNode *p;
	SqQueue *qu;							//定义环形队列指针
	InitQueue(qu);							//初始化队列
	int visited[MAXV];            			//定义顶点访问标志数组
	for (i=0;i<G->n;i++) visited[i]=0;		//访问标志数组初始化
	printf("%2d",v); 						//输出被访问顶点的编号
	visited[v]=1;              				//置已访问标记
	enQueue(qu,v);
	while (!QueueEmpty(qu))       			//队不空循环
	{	
		deQueue(qu,w);						//出队一个顶点w
		p=G->adjlist[w].firstarc; 			//指向w的第一个邻接点
		while (p!=NULL)						//查找w的所有邻接点
		{	
			if (visited[p->adjvex]==0) 		//若当前邻接点未被访问
			{
				printf("%2d",p->adjvex);  	//访问该邻接点
				visited[p->adjvex]=1;		//置已访问标记
				enQueue(qu,p->adjvex);		//该顶点进队
           	}
           	p=p->nextarc;              		//找下一个邻接点
		}
	}
	printf("\n");
}

int main()
{
	AdjGraph *G;
	int A[MAXV][MAXV]={{0,1,0,1,1},{1,0,1,1,0},
			{0,1,0,1,1},{1,1,1,0,1},{1,0,1,1,0}};
	int n=5, e=8;
	CreateAdj(G,A,n,e);			//建立《教程》中图8.1(a)的邻接表
	printf("图G的邻接表:\n");
	DispAdj(G);					//输出邻接表G
	printf("广度优先序列:");BFS(G,2);printf("\n");
	DestroyAdj(G);				//销毁邻接表
	return 1;
}
#include "graph.cpp"
int visited[MAXV]={0};
void DFS(AdjGraph *G,int v)  
{
	ArcNode *p;
	visited[v]=1;                   //置已访问标记
	printf("%d  ",v); 				//输出被访问顶点的编号
	p=G->adjlist[v].firstarc;      	//p指向顶点v的第一条弧的弧头结点
	while (p!=NULL) 
	{
		if (visited[p->adjvex]==0)	//若p->adjvex顶点未访问,递归访问它
			DFS(G,p->adjvex);    
		p=p->nextarc;              	//p指向顶点v的下一条弧的弧头结点
	}
}
int main()
{
	AdjGraph *G;
	int A[MAXV][MAXV]={{0,1,0,1,1},{1,0,1,1,0},
			{0,1,0,1,1},{1,1,1,0,1},{1,0,1,1,0}};
	int n=5, e=8;
	CreateAdj(G,A,n,e);			//建立《教程》中图8.1(a)的邻接表
	printf("图G的邻接表:\n");
	DispAdj(G);					//输出邻接表G
	printf("深度优先序列(递归):");DFS(G,2);printf("\n");
	DestroyAdj(G);				//销毁邻接表
	return 1;
}

四、实验结果
(实验结果截图)
1.
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

五、实验心得
(心得体会,书写要详细、具体,包括问题及解决办法或者方法)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

半夏风情

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

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

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

打赏作者

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

抵扣说明:

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

余额充值