数据结构实验六 图的操作实现

数据结构实验 图的操作实现

一、实验目的

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

2、 掌握图的创建过程

二、实验内容

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

图的创建代码参考教材.

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

 

#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
typedef struct
 {
 	char 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;
 	int numVertexes; 
 }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);
 	G->numVertexes++;
 }
 
 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;
 	int col;
 } rowcol;
 
 void CreatGraph(MatrixGraph *G,char 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 main(void)
{
	MatrixGraph g1;
	char a[]={'1','2','3','4','5'};
	rowcol rc[]={{0,1},{0,2},{0,3},{0,4},{2,4},{1,3}};
	int n=5,e=6;
	int i,j;
	CreatGraph(&g1,a,n,rc,e);
	for(i=0;i<g1.Vertices.size;i++)
	printf("%c ",g1.Vertices.list[i]);
	printf("\n");
	printf("juzhengwei\n");
	for(i=0;i<g1.Vertices.size;i++)
	{
		for(j=0;j<g1.Vertices.size;j++)
		printf("%5d ",g1.edge[i][j]);
		printf("\n");
		
	}

	return 0;
} 
 

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

#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
typedef struct
 {
 	char 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;
 	int numVertexes; 
 }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;
	G->numVertexes=0; 
	ListInitiate(&G->Vertices) ;
 }
 
 void InsertVertex(MatrixGraph *G,int vertex)
 {
 	ListInsert(&G->Vertices,G->Vertices.size,vertex);
 	G->numVertexes++;
 }
 
 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;
 	int col;
 } rowcol;
 
 void CreatGraph(MatrixGraph *G,char 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);
 }
 
 
typedef struct QNode //结点结构
{
	int  data;
	struct QNode *next;
}QNode,*QueuePtr;

  typedef struct //队列的链表结构
{
	QueuePtr front,rear;//队头、队尾指针
}LinkQueue;
 
//初始化队列:
int initQueue(LinkQueue *q)
{
	q->front = q->rear = (QueuePtr)malloc(sizeof(QNode));
	if(!q->front)
		return 0;
	q->front->next = NULL;
 
	return 1;
}
 
//入队:插入元素e为q的新的队尾元素
int EnQueue(LinkQueue *q,int e)
{
	QueuePtr s = (QueuePtr)malloc(sizeof(QNode));
	if(!s)//存储分配失败
		return 0;
	s->data = e;
	s->next = NULL;
	q->rear->next = s;
	q->rear = s;
 
	return 1;
}
 
//出队
//若队列不为空,删除q的队头元素,用e返回其值,并返回OK,否则返回ERROR
int DeQueue(LinkQueue *q,int *e)
{
	
	QueuePtr p;
 
	if(q->front==q->rear)
		return 0;
	p = q->front->next;
	*e = p->data;
	q->front->next = p->next;
 
	if(q->rear==p)//若队头是队尾,则删除后将rear指向头结点
		q->rear = q->front;
	free(p);
	return 1;
}
 
//判断是否为空队列,若为空队列则返回1,否则返回0
int QueueEmpty(LinkQueue q)
{
	if(q.front == q.rear)
		return 1;
	return 0;
}

int visited[100];//判断访问 


void DFS(MatrixGraph G,int i)
{
	int j;
	visited[i] = 1;
	printf("%c ",G.Vertices.list[i]);
	for(j=0;j<G.numVertexes;j++)
		if(G.edge[i][j]==1 && !visited[j])
			DFS(G,j);//对未访问的邻接顶点递归调用
}
 
//邻接矩阵的深度遍历算法
void DFSTraverse(MatrixGraph G)
{
	int i;
	for(i=0;i<G.numVertexes;i++)
		visited[i]=0;//初始所有顶点状态都是未被访问过
	for(i=0;i<G.numVertexes;i++)
		if(!visited[i])
			DFS(G,i);
			}

//邻接矩阵的广度遍历算法
void BFSTraverse(MatrixGraph G)
{
	int i,j;
	LinkQueue Q;
 
	for(i=0;i<G.numVertexes;i++)
	{
		visited[i] = 0;
	}
 
	initQueue(&Q);				
 
	for(i=0;i<G.numVertexes;i++)
	{
		if(!visited[i])			
		{
			visited[i] = 1;	
			printf("%c ",G.Vertices.list[i]);
			EnQueue(&Q,i);		
 
			while(!QueueEmpty(Q))//若当前顶点不为空
			{
				DeQueue(&Q,&i);	 //将队中元素出队列,赋值给i
				for(j=0;j<G.numVertexes;j++)
				{
				
					if(G.edge[i][j] ==1 && !visited[j])
					{
						visited[j] = 1;//将找到的此顶点标记为已访问
						printf("%c ",G.Vertices.list[j]);
						EnQueue(&Q,j);//将找到的此顶点入队列
					}
				}
			}
		}
	}
}

 int main(void)
{
	MatrixGraph g1;
	char a[]={'1','2','3','4','5'};
	rowcol rc[]={{0,1},{0,2},{0,3},{0,4},{2,4},{1,3}};
	int n=5,e=6;
	int i,j;
	CreatGraph(&g1,a,n,rc,e);
	for(i=0;i<g1.Vertices.size;i++)
	printf("%c ",g1.Vertices.list[i]);
	
	printf("\n");
	printf("DFS:");
	DFSTraverse(g1);
	printf("BFS:");
	BFSTraverse(g1);
	return 0;
} 
 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值