图中以邻接矩阵中两种遍历方法以及删减顶点和边的操作(C++)

图的广度优先遍历:

从图中某顶点v出发进行广度优先遍历的基本思想是:

(1)访问顶点v;

(2)依次访问v的各个未被访问的邻接点,v1,v2,v3……,vk;

(3)分别从v1,v2,……,vk出发依次访问它们未被访问的邻接点,并使“先被访问顶点的邻接点”先于“后被访问顶点的邻接点”被访问。直至图中所有与顶点v有路径相通的顶点都被访问到。

广度优先遍历图是以顶点v为起始点,由近至远,依次访问和v有路径相通且路径长度为1,2等的顶点。为了使“先被访问顶点的邻接点”先于“后被访问顶点的邻接点”被访问,需设置队列储存已被访问的顶点。伪代码如下:

1.初始化队列Q;

2.访问顶点v;visited[v]=1;顶点v入队列Q;

3.while(队列Q非空)

       3.1 v=队列Q的队头元素出队;

       3.2 w=顶点v的第一个邻接点;

       3.3 while(w存在)

            3.3.1 如果w未被访问,则访问顶点w;visited[w]=1;顶点w入队列Q;

            3.3.2 w=顶点v的下一个邻接点;

 

图的深度优先遍历:

从图的某个顶点v出发进行深度优先遍历的基本思想是:

(1)访问顶点v;

(2)从v的未被访问的邻接点中选取一个顶点w,从w出发进行深度优先遍历;

(3)重复上述两步,直至图中所有和v相通的顶点都被访问到;

以下是伪代码:

1.访问顶点v;visited[v]=1;

2.w=顶点v的第一个邻接点;

3. while(w存在)

    3.1 if(w为被访问)从顶点w出发递归执行该算法;

    3.2 w=顶点v的下一个邻接点;

 

 

下面是一道关于图的编程题目:

编写程序实现以下功能:
(1)创建一个无向图(采用邻接矩阵方式存储);
(2)分别输出从结点0开始的一个深度优先遍历序列和广度优先遍历序列;
(3)编写函数实现结点的增加或删除;
(4)编写函数实现边的增加或删除;
    vertex= 0 1 2 3 4 5
                |0 1 1 0 0 1|
                |1 0 1 0 0 0|
arc[6][6]= |1 1 0 1 1 0|
                |0 0 1 0 1 1|
                |0 0 1 1 0 0|
                |1 0 0 1 0 0|

以下是C++的实现:

/*
编写程序实现以下功能:
(1)创建一个无向图(采用邻接矩阵方式存储);
(2)分别输出从结点0开始的一个深度优先遍历序列和广度优先遍历序列;
(3)编写函数实现结点的增加或删除;
(4)编写函数实现边的增加或删除;
      vertex=   0 1 2 3 4 5
               |0 1 1 0 0 1|
	       |1 0 1 0 0 0|
    arc[6][6]= |1 1 0 1 1 0|
	       |0 0 1 0 1 1|
	       |0 0 1 1 0 0|
	       |1 0 0 1 0 0|
*/
#include<iostream>
using namespace std;
const int MaxSize = 10;
int visited[MaxSize] = { 0,0,0,0,0,0,0,0,0,0 };
class MGraph
{
public:
	MGraph(int a[], int n, int e, int b[][6]);//初始化n个顶点e条边的图
	~MGraph() {};
	void DFSTraverse(int v);//深度优先遍历
	void BFSTraverse(int v);//广度优先遍历
	void InsertVex(int i, int value);//增加顶点
	void DeleteVex(int i);//删除顶点
	void InsertArc(int i, int j);//增加边
	void DeleteArc(int i, int j);//删除边
private:
	int vertex[MaxSize];//存放顶点的数组
	int arc[MaxSize][MaxSize];//存放边的数组
	int vertexNum, arcNum;//顶点和边数
};

MGraph::MGraph(int a[], int n, int e, int b[][6])
{
	vertexNum = n; arcNum = e;
	for (int i = 0; i < vertexNum; i++)
		vertex[i] = a[i];//将顶点数据存入数组
	for (int a = 0; a < vertexNum; a++)
		for (int b = 0; b < vertexNum; b++)
			arc[a][b] = 0;
	for (int k = 0; k < 6; k++)
		for (int j = 0; j < 6; j++)
			arc[k][j] = b[k][j];//初始化arc数组
}
void MGraph::DFSTraverse(int v)
{
	cout << vertex[v];
	visited[v] = 1;
	for (int j = 0; j < vertexNum; j++)
		if (arc[v][j] == 1 && visited[j] == 0)
			DFSTraverse(j);//递归深度优先遍历
}
void MGraph::BFSTraverse(int v)
{
	int visited[MaxSize] = { 0,0,0,0,0,0,0,0,0,0 };//对应每个顶点的被访问状态,0为未访问,1为已访问
	int Q[MaxSize];
	int front, rear;
	front = rear = -1;//初始化队列,假设队列采用顺序储存,且不会发生溢出
	cout << vertex[v];	visited[v] = 1;	Q[++rear] = v;//被访问顶点入队
	while (front != rear)//队列为空时遍历结束
	{
		int j;
		v = Q[++front];//始终用v保存每一趟遍历的其实顶点,这里是将队头元素出队并送到v中
		for (j = 0; j < vertexNum; j++)
			if (arc[v][j] == 1 && visited[j] == 0)
			{
				cout << vertex[j];
				visited[j] = 1;
				Q[++rear] = j;
			}
	}
	cout << endl;
}
void MGraph::InsertVex(int i, int value)//i为所增加顶点对应的下标
{
	vertex[i] = value;
	for (int j = 0; j <= i; j++)
	{
		arc[i][j] = 0;
		arc[j][i] = 0;
	}
	vertexNum++;
}
void MGraph::DeleteVex(int i)//i为所删除顶点所对应的下标
{
	int t = i,temp[MaxSize][MaxSize];
	for (int j = t + 1; j < vertexNum; j++)
		vertex[t++] = vertex[j];
	for (int x = 0; x <vertexNum; x++)//删除邻接矩阵中对应的行和列,实质是后一行(列)覆盖原有的值(依次覆盖)
		for (int y = i; y < vertexNum; y++)
		{
			if (y == vertexNum - 1)
			{
				arc[x][y] = 0;
				arc[y][x] = 0;
			}
			arc[x][y-1] = arc[x][y];
			arc[y-1][x] = arc[y][x];
		}
		vertexNum--;
}
void MGraph::InsertArc(int i, int j)//i,j为增加边所依附的顶点下标
{
	arc[i][j] = 1; arc[j][i] = 1;
	arcNum++;
}
void MGraph::DeleteArc(int i, int j)//i,j分别是删除边所依附的顶点下标
{
	arc[i][j] = 0; arc[j][i] = 0;
	arcNum--;
}
int main()
{
	int a[6] = { 0,1,2,3,4,5 };
	int b[6][6] = { {0,1,1,0,0,1},{1,0,1,0,0,0},{1,1,0,1,1,0},{0,0,1,0,1,1},{0,0,1,1,0,0},{1,0,0,1,0,0} };//更根据题目要求生成邻接矩阵
	MGraph T(a, 6, 6, b);
	cout << "深度优先遍历序列:";
	T.DFSTraverse(0);
	cout << endl << "广度优先遍历序列:";
	T.BFSTraverse(0);
	T.InsertVex(7, 6);//增加下标为7,值为6的顶点
	cout << "增加下标为7值为6的顶点后广度优先遍历序列:";
	T.BFSTraverse(0);
	T.DeleteVex(5);//删除下标为5的顶点
	cout << "删除下标为5的顶点后广度优先遍历序列:";
	T.BFSTraverse(0);
	T.InsertArc(1, 4);//增加边(1,4)
	cout << "增加边(1,4)后的广度优先遍历序列:";
	T.BFSTraverse(0);
	T.DeleteArc(1, 4);//删除边(1,4)
	cout << "删除边(1,4)后的广度优先遍历序列:";
	T.BFSTraverse(0);
	return 0;
}

     

    原文作者:数据结构之图
    原文地址: https://blog.csdn.net/song_10/article/details/85081932
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞