2021-11-07 图的基本操作

【问题描述】

给定一个无向图和一个图顶点,编程输出该图删除给定顶点前后按深度优先遍历及广度优先遍历方式遍历的图顶点序列。

给定的无向图和图顶点满足以下要求:

1、无向图的顶点个数n大于等于3,小于等于100,输入时顶点编号用整数0~n-1表示;

2、无向图在删除给定顶点前后都是连通的;

3、无论何种遍历,都是从编号为0的顶点开始遍历,访问相邻顶点时按照编号从小到大的顺序访问;

4、删除的顶点编号不为0。

【输入形式】

先从标准输入中输入图的顶点个数和边的个数,两整数之间以一个空格分隔,然后从下一行开始分行输入每条边的信息(用边两端的顶点编号表示一条边,以一个空格分隔顶点编号,边的输入次序和每条边两端顶点编号的输入次序可以是任意的,但边不会重复输入),最后在新的一行上输入要删除的顶点编号。

【输出形式】

分行输出各遍历顶点序列,顶点编号之间以一个空格分隔。先输出删除给定顶点前的深度优先遍历顶点序列和广度优先遍历顶点序列,再输出删除给定顶点后的深度优先遍历顶点序列和广度优先遍历顶点序列。

输入的无向图有9个顶点,10条边(如下图所示),要删除的顶点编号为3

【样例输入】

9 10                

0 1

0 2

1 4

1 3

1 8

8 6

3 6

7 2

7 5

5 2

3

【样例输出】

0 1 3 6 8 4 2 5 7

0 1 2 3 4 8 5 7 6

0 1 4 8 6 2 5 7

0 1 2 4 8 5 7 6

【样例说明】

输入的无向图有9个顶点,10条边(如图所示),要删除的顶点编号为3。

从顶点0开始,按照深度优先和广度优先遍历的顶点序列分别为:0 1 3 6 8 4 2 5 7和0 1 2 3 4 8 5 7 6。

删除编号为3的顶点后,按照深度优先和广度优先遍历的顶点序列分别为:0 1 4 8 6 2 5 7和0 1 2 4 8 5 7 6。

【运行结果如下】

【代码如下】

代码1:使用队列的顺序存储结构(循环队列)

#include<stdio.h> 
#define MVNum  40	//最大顶点个数  

//------队列的顺序存储结构(循环队列)------
typedef struct{
	int data[MVNum];
	int front;
	int rear;
}SqQueue;
void InitQueue(SqQueue &Q)
{	
	//初始化队列 
	Q.front = Q.rear = 0;
}
bool QueueEmpty(SqQueue &Q)
{	
	//队列判空 
	if (Q.front == Q.rear)
		return true;
	return false;
}
bool EnQueue(SqQueue &Q,int e)
{	
	//入队 
	if ((Q.rear+1)%MVNum == Q.front)
		return false;
	Q.data[Q.rear++] = e;
	Q.rear = Q.rear%MVNum;
	return true;
}
bool DeQueue(SqQueue &Q,int &e)
{	
	//出队 
	if (QueueEmpty(Q))	return false;
	e = Q.data[Q.front++];
	Q.front = Q.front%MVNum;
	return true;
}

//------图的的数组(邻接矩阵)存储表示------ 
typedef struct {
	int vexs[MVNum];		//顶点向量
	int	arcs[MVNum][MVNum];	//邻接矩阵
	int visited[MVNum];		//访问标志数组
	int	vexnum;				//顶点数
	int arcnum;		 		//弧数
}MGraph;
int LocateVex(MGraph G,int v)
{
	for (int i = 0; i < G.vexnum; i++) 
		if (G.vexs[i] == v)	return i;
	return -1;
}
void CreateUDN(MGraph &G)
{
	//构造无向网G
	int i, j, k;
	int v1, v2; 
	scanf("%d %d",&G.vexnum,&G.arcnum);	//顶点总数和弧总数
	for (i = 0; i < G.vexnum; i++){
		G.vexs[i] = i;		//构造顶点向量	
		G.visited[i] = 0;	//初始化标记数组 
	}
	for (i = 0; i < G.vexnum; i++)//初始化邻接矩阵 
		for (j = 0; j < G.vexnum; j++)	
			G.arcs[i][j] = 0;			
	for (k = 0; k < G.arcnum; k++){//构造邻接矩阵
		scanf("%d %d",&v1,&v2);
		i = LocateVex(G,v1);
		j = LocateVex(G,v2);
		G.arcs[i][j] = 1;
		G.arcs[j][i] = 1;
	}//for
}
void Delete(MGraph &G,int del)
{
	//删除一个图中顶点 
	for (int i=0; i<G.vexnum; i++){
		G.arcs[del][i]=0;
		G.arcs[i][del]=0;
	}	
}
void InitVisited(MGraph &G)
{	
	//初始化标记数组 
	for (int i=0; i<G.vexnum; i++)
		G.visited[i] = 0;
	printf("\n");
}
void DFS(MGraph &G,int i) 
{
	//深度搜索
	printf("%d ",G.vexs[i]);
	G.visited[i] = 1;
	for (int j=0; j<G.vexnum; j++) 
		if (G.arcs[i][j]!=0 && !G.visited[j])
			DFS(G,j);		
}
void BFS(MGraph &G,int i)
{	
	//广度搜索 
	SqQueue Q;
	InitQueue(Q);
	EnQueue(Q,i);
	G.visited[i] = 1;
	int e = 0;
	while (!QueueEmpty(Q))
	{
		DeQueue(Q,e);
		printf("%d ",e);
		for (int j=0; j<G.vexnum; j++)
			if (G.arcs[e][j] && !G.visited[j])
			{
				EnQueue(Q,j);
				G.visited[j]=1;
			}//if
	}//while 
}

int main()
{
	int del;
	MGraph G; 
	CreateUDN(G); 	
	scanf("%d",&del);//删除的元素 
	DFS(G,0);
	InitVisited(G);
	BFS(G,0);
	InitVisited(G);
	Delete(G,del);	//删除元素后 
	DFS(G,0);
	InitVisited(G);
	BFS(G,0);
	InitVisited(G);
	return 0;
}

代码2:使用队列的链式存储结构

#include<stdio.h> 
#include<stdlib.h>
#define MVNum  20 					//最大顶点个数  

//------队列的链式存储结构------ 
typedef struct QNode{                     
    int data;
    struct QNode *next;
}QNode,*QueuePtr;
typedef struct{
    QueuePtr front;
    QueuePtr rear;
}LinkQueue;
void InitQueue(LinkQueue &Q)
{
	//初始化队列 
	Q.front = Q.rear = (QueuePtr)malloc(sizeof(QNode));
	if (!Q.front) exit(-1);
	Q.front->next = NULL;
}
bool QueueEmpty(LinkQueue &Q) 
{
	//队列判空 
	if (Q.front == Q.rear)
		return true;
	return false;
}
void EnQueue(LinkQueue &Q,int e)
{
	//入队 
	QueuePtr pre;	
	pre = (QueuePtr)malloc(sizeof(QNode));
	if (!pre) exit(-1);	
	pre->data = e;	 
	pre->next = NULL; 
	Q.rear->next = pre;
	Q.rear = pre;
}
void DeQueue(LinkQueue &Q,int &e)
{
	//出队 
	QueuePtr pre;
	if (Q.front == Q.rear) exit(-1);
	pre = Q.front->next;
	e = pre->data;
	Q.front->next = pre->next;	 
	if (Q.rear == pre)	Q.rear=Q.front;
	free(pre);
}

//------图的的数组(邻接矩阵)存储表示------ 
typedef struct {
	int vexs[MVNum];		//顶点向量
	int	arcs[MVNum][MVNum];	//邻接矩阵
	int visited[MVNum];		//访问标志数组
	int	vexnum;				//顶点数
	int arcnum;		 		//弧数
}MGraph;
int LocateVex(MGraph G,int v)
{
	for (int i = 0; i < G.vexnum; i++) 
		if (G.vexs[i] == v)	return i;
	return -1;
}
void CreateUDN(MGraph &G)
{
	//构造无向网G
	int i, j, k;
	int v1, v2; 
	scanf("%d %d",&G.vexnum,&G.arcnum);	//顶点总数和弧总数
	for (i = 0; i < G.vexnum; i++){
		G.vexs[i] = i;//构造顶点向量	
		G.visited[i] = 0;//初始化标记数组 
	}
	for (i = 0; i < G.vexnum; i++)		//初始化邻接矩阵 
		for (j = 0; j < G.vexnum; j++)	
			G.arcs[i][j] = 0;			
	for (k = 0; k < G.arcnum; k++){		//构造邻接矩阵
		scanf("%d %d",&v1,&v2);
		i = LocateVex(G,v1);
		j = LocateVex(G,v2);
		G.arcs[i][j] = 1;
		G.arcs[j][i] = 1;
	}//for
}
void Delete(MGraph &G,int del)
{//删除一个图中顶点 
	for(int i=0; i<G.vexnum; i++){
		G.arcs[del][i]=0;
		G.arcs[i][del]=0;
	}	
}
void InitVisited(MGraph &G)
{//初始化标记数组 
	for (int i=0; i<G.vexnum; i++)
		G.visited[i] = 0;//初始化标记数组 
	printf("\n");
}
void DFS(MGraph &G,int i) 
{
	//深度搜索
	printf("%d ",G.vexs[i]);
	G.visited[i] = 1;
	for (int j=0; j<G.vexnum; j++) 
		if(G.arcs[i][j]!=0 && !G.visited[j])
			DFS(G,j);		
}
void BFS(MGraph &G,int i)
{
	//广度搜索 
	LinkQueue Q;
	InitQueue(Q);
	EnQueue(Q,i);
	G.visited[i] = 1;
	int e = 0;
	while (!QueueEmpty(Q))
	{
		DeQueue(Q,e);
		printf("%d ",e);
		for (int j=0; j<G.vexnum; j++)
			if (G.arcs[e][j] && !G.visited[j])
			{
				EnQueue(Q,j);
				G.visited[j]=1;
			}//if
	}//while 
}

int main()
{
	int del;
	MGraph G; 
	CreateUDN(G); 	
	scanf("%d",&del);//删除的元素 
	DFS(G,0);
	InitVisited(G);
	BFS(G,0);
	InitVisited(G);
	Delete(G,del);//删除元素后 
	DFS(G,0);
	InitVisited(G);
	BFS(G,0);
	InitVisited(G);
	return 0;
}

本文章仅供学习和参考!

欢迎交流~ 

猜你喜欢

转载自blog.csdn.net/m0_58489132/article/details/121191047
今日推荐