《数据结构与算法那》第七次 广度、深度优先遍历 图及图的遍历(下)

《数据结构与算法那》第七次课实验内容

图及图的遍历(下)

实验目的:

  1. 熟悉图的两种存储结构:邻接矩阵和邻接链表。
  2. 掌握在图的邻接表存储结构上的遍历算法的实现。

实验内容:

  1. 在已经开发好的c++类adjacencyGraph中,添加两个成员函数,BFSpanningTree和DFSspanningTree分别输出该图的广度优先生成树和深度优先生成树。
  2. 在已经开发好的c++类linkedGraph中,添加两个成员函数,BFSpanningTree和DFSpanningTree分别输出该图的广度优先生成树和深度优先生成树。
  3. 两个存储方式任选其一完成。

江米条想说的话:

(用的是临界数组,这个题链表比矩阵更简单,矩阵都会了,还怕链表该干什么)

这次的代码和上次的代码几乎一样,就多了两个函数而已。没看明白的看我写的《数据结构与算法》第六次去。。。。

下面我给大家讲一下这两个算法:BFS(广度优先)和DFS(深度优先)

广度优先BFS (你们记住Breadth就行):

简单地说:广度的意思就是一层一层的遍历。

看图:

《《数据结构与算法那》第七次 广度、深度优先遍历 图及图的遍历(下)》

从A点开始访问顺序:A->B->D->E->C->F->G

广度遍历是:

1:访问A

2:访问B,D,E(B,D,E都是A的邻接点,按照顺序访问)

3:访问C(访问B的邻接点C,访问完了C点之后,开始从D,E找)

4:访问F(因为D的邻接点没有,所以从B,D,E中的E点开始找E的下一个,即F)

5:访问G(访问F的下一个G)

6:G点之后没有了,往上找发现F也没未访问的子节点了,在往上也发现:E也没有未访问的子节点了(B,D,E都没了),所以再往上看A也没有未访问的子节点了,至此,访问结束。

 

深度优先DFS (你们记住Depth就行):

简单地说:深度就是沿着一条路走到底,走完了再折回来走其他的路。

看图:

《《数据结构与算法那》第七次 广度、深度优先遍历 图及图的遍历(下)》

从A点开始访问的顺序:A->B->C->D->E->F->G

深度遍历是:(邻接链表)

1: 访问A

2: 访问B(在这个过程里面,A的邻接点有B、D、E,但是B的顺序在前面,所以先访问B)

3: 访问C(在这个过程里面,B的邻接点有C、D,但是C的顺序在前面,所以先访问C)

4: 访问D(C之后没邻接点了,所以往上倒一层,找B的另一个邻接点D)

5: 访问E(D之后没邻接点了,所以往上倒一层,B之后的点都被访问了,再往上倒一层,找A的另一个邻接点E

6: 访问F(E的下一个是F)

7: 访问G(F的下一个是G)

8: G访问没了,往上倒一层到了F,F的邻接点都被访问了,再往上倒一层到了E,E的邻接点都被访问了,再再往上倒一层到了A,A的邻接点也都被访问了,至此,访问结束

 

头文件:

#include<iostream>
using namespace std;

class adjacencyGraph
{
public:
	adjacencyGraph(int n, int e);
	void setElement(int n, int value);
	int getIndex(int value);
	void insertEdge(int vertex1, int vertex2);
	void eraseEdge(int vertex1, int vertex2);
	void BFSpanningTree(int v);
	void DFSpanningTree(int v);
	void dfs(int v);
	void outputGraph();
private:
	int **matrix;
	int *element;
	int numberOfVertices;
	int numberOfEdges;
	int *reach = new int[numberOfVertices];
	int count = 0;
};
adjacencyGraph::adjacencyGraph(int n, int e)
{
	numberOfVertices = n;
	numberOfEdges = e;
	matrix = new int *[numberOfVertices];
	for (int i = 0; i < numberOfVertices; i++)
		matrix[i] = new int[numberOfVertices];
	for (int i = 0; i < numberOfVertices; i++)
		for (int j = 0; j < numberOfVertices; j++)
			matrix[i][j] = 0;
	element = new int[numberOfVertices];
}
void adjacencyGraph::setElement(int n, int value)
{
	element[n - 1] = value;
}
int adjacencyGraph::getIndex(int value)
{
	for (int i = 0; i < numberOfVertices; i++)
		if (element[i] == value)
			return i;
}
void adjacencyGraph::insertEdge(int vertex1, int vertex2)
{
	matrix[vertex1][vertex2] = 1;
	matrix[vertex2][vertex1] = 1;
}
void adjacencyGraph::eraseEdge(int vertex1, int vertex2)
{
	matrix[vertex1][vertex2] = 0;
	matrix[vertex2][vertex1] = 0;
}
void adjacencyGraph::BFSpanningTree(int v)
{
	int l = 0, r = 1;
	for (int i = 0; i < numberOfVertices; i++)
		reach[i] = NULL;
	reach[0] = v;
	while (reach[numberOfVertices - 1] == NULL)
	{
		int tl = l, tr = r;
		l = r;
		for (tl; tl < tr; tl++)
		{
			int index = getIndex(reach[tl]);
			for (int j = 0; j < numberOfVertices; j++)
				if (matrix[index][j] == 1)
				{
					int k;
					for (k = 0; k < r; k++)
						if (element[j] == reach[k])
							break;
					if (k == r)
					{
						reach[r] = element[j];
						r++;
					}
				}
		}
	}
	cout << "这个无向图的广度优先搜索为:";
	for (int i = 0; i < numberOfVertices; i++)
		cout << reach[i];
	cout << endl;
}
void adjacencyGraph::DFSpanningTree(int v)
{
	for (int i = 0; i < numberOfVertices; i++)
		reach[i] = NULL;
	reach[0] = v;
	dfs(v);
	for (int i = 0; i < numberOfVertices; i++)
		cout << reach[i];
	cout << endl;
}
void adjacencyGraph::dfs(int v)
{
	int index = getIndex(v);
	for (int i = 0; i < numberOfVertices; i++)
		//if(reach[i]==0)
		if (matrix[index][i] == 1)
		{
			int k;
			for (k = 0; k < count; k++)
				if (element[i] == reach[k])
					break;
			if (k == count)
			{
				bool t = false;//设置这个变量是为了防止出现从父结点再次遍历到子节点的情况,比如两个父结点都连着一个子节点。
				for(int a=0;a<count+1;a++)
					if (element[i] == reach[a])
					{
						t = true;
						break;
					}
				if (t == false)
				{
					count++;
					reach[count] = element[i];
					dfs(reach[count]);
				}
			}
		}
}
void adjacencyGraph::outputGraph()
{
	for (int i = 0; i < numberOfVertices; i++)
	{
		for (int j = 0; j < numberOfVertices; j++)
			cout << matrix[i][j] << " ";
		cout << endl;
	}
}

主函数:

#include<iostream>
#include"adjacencyGraph.h"
using namespace std;
int main()
{
	adjacencyGraph *temp;
	temp = new adjacencyGraph(0, 0);
	while (1)
	{
		cout << "1.用邻接矩阵描述一个无向图" << endl;
		cout << "2.删除无向图的一条边" << endl;
		cout << "3.对无向图广度优先搜索"<<endl;
		cout<< "4.对无向图深度优先搜索"<<endl;
		cout << "0.退出" << endl;
		int option;
		cin >> option;
		switch (option)
		{
		case 1:
			{
				int n, e;
				cout << "请输入顶点的数目:";
				cin >> n;
				cout << "请输入边的数目:";
				cin >> e;
				temp = new adjacencyGraph(n, e);
				for (int i = 1; i <= n; i++)
				{
					int value;
					cout << "请输入第" << i << "个顶点";
					cin >> value;
					temp->setElement(i, value);
				}
				for (int i = 1; i <= e; i++)
				{
					int value1, value2;
					cout << "请输入第" << i << "条边的第1个顶点:";
					cin >> value1;
					cout << "请输入第" << i << "条边的第2个顶点:";
					cin >> value2;
					temp->insertEdge(temp->getIndex(value1), temp->getIndex(value2));
				}
				temp->outputGraph();
			}
			break;
		case 2:
			{
				int value1, value2;
				cout << "请输入要删除边的第一个顶点:";
				cin >> value1;
				cout << "请输入要删除边的第二个顶点:";
				cin >> value2;
				temp->eraseEdge(temp->getIndex(value1), temp->getIndex(value2));
				temp->outputGraph();
			}
			break;
		case 3:
			{
				int v;
				cout<< "请输入搜索的起点值:";
				cin>>v;
				temp->BFSpanningTree(v);
			}
			break;
		case 4:
		{
			int v;
			cout << "请输入搜索的起点值:";
			cin >> v;
			temp->DFSpanningTree(v);
		}
		break;
		case 0:
			return 0;
		default:
			break;
		}
	}
}

呼,结束了,打字画图真的好累好累的。

代码就这两个文件,上面的是头文件,下面的是主函数。就不上传链接啦!

如果有问题请联系我 QQ:1239825268

备注:CSDN

共勉!

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