数据结构---图--图的遍历-DFS-BFS

目录

遍历要求:

DFS:走迷宫(深度优先遍历)

BFS:(广度优先遍历)

备注:顶点类、边类、主函数及其打印函数,查找顶点下标函数所有函数集合!!

 遍历运行结果


遍历要求:

 图从某一顶点出发,把每一个顶点访问有且只有一次

邻接表如下:

DFS:走迷宫(深度优先遍历)

从第一个顶点开始,走第一个顶点的第一个邻接顶点

void LinkGraph::DFS(int v, bool* visited)
{
	cout << m_VerArr[v].m_value<<" ";
	visited[v] = true;
	Edge*p=m_VerArr[v].m_list;//邻接表指针
	while (p != nullptr)//保证邻接表里有东西
	{
		//从没有被访问过的邻接表里开始继续DFS
		if (!visited[p->m_index])//判断是否被访问过 
		{
			DFS(p->m_index,visited);
		}
		p = p->m_next;
	}

}
void LinkGraph::DFS(char v)
{
	int p = GetVertexIndex(v);//获取下标
	if (p == -1)
		return;
	bool* visited = new bool[m_NumEdge];//定义num个数的bool数组
	for (int i = 0; i < m_NumVertex; ++i)//置false
	{
		visited[i] = false;
	}
	DFS(p, visited);//递归调用+打印
	delete[] visited;
	visited = nullptr;
	cout << endl;
}

BFS:(广度优先遍历)

先找第一个顶点的所有邻接顶点,再找所有邻接顶点的所有没有被访问过的邻接顶点

 用队列实现

  1. 第一个顶点入队,队头元素出队,访问队头元素的所有邻接顶点,全部入队,
  2. 如果队头不为空,出队,访问队头元素的所有邻接顶点,全部入队

构建一个判断邻接顶点是否被访问的

如果邻接顶点已经被访问过就设为1,没有被访问过就设为0.

void LinkGraph::BFS(char v)
{
	int p = GetVertexIndex(v);//获得队头元素的下标
	if (p == -1)//判断邻接顶点是否存在
		return ;
	bool* visited = new bool[m_NumVertex];//定义判断顶点是否被访问过的数组
	for (int i = 0; i < m_NumVertex; ++i)//遍历数组
	{
		visited[i] = false;//全部置为false,即未访问过
	}
	queue<int > qq;//定义队列
	qq.push(p);//队头元素入队
	cout << m_VerArr[p].m_value;//!!刚刚忘了写这句
	visited[p] = true;//遍历数组中被访问过置为true,即已被访问过
	cout << " ";
	int front;//队头顶点下标
	Edge* plist = nullptr;//指向队头元素的结构体指针
	while (!qq.empty())//判断队列是否为空
	{
		front = qq.front();//获取并保存队列的头的下标
		qq.pop();//头顶点出队
		plist = m_VerArr[front].m_list;//plist被赋值为根据下标找到所指向的顶点元素
		while (plist != nullptr)//判断是否有下一个邻接顶点
		{
			if (!visited[plist->m_index])//判断是否访问过,如果未被访问过则进入if语句
			{
				cout << m_VerArr[plist->m_index].m_value << " ";//打印元素
				visited[plist->m_index] = true;//判访问数组置为true
				qq.push(plist->m_index); //入队
			}
		plist = plist->m_next;
		}
	}
	cout << endl;
}

备注:顶点类、边类、主函数及其打印函数,查找顶点下标函数所有函数集合!!

#include<iostream>
using namespace std;
#include<queue>

//图从某一顶点出发,把每一个顶点访问有且只有一次
class Edge
{
public:
	Edge() :m_next(nullptr) {}
	Edge(int index) :m_index(index), m_next(nullptr) {}
	int m_index;
	Edge* m_next;
};

class Vertex
{
public:
	Vertex() :m_list(nullptr) {}
	Vertex(int v) :m_value(v), m_list(nullptr) {}
	char m_value;
	Edge* m_list;
};
#define SIZE 10
class LinkGraph
{
public:
	LinkGraph() :m_MaxVertex(SIZE), m_NumVertex(0), m_NumEdge(0)
	{
		m_VerArr = new Vertex[m_MaxVertex];
	}
	~LinkGraph()
	{
		if (m_VerArr != nullptr)
		{
			delete[]m_VerArr;
			m_VerArr = nullptr;
		}
	}
	void InsertVertex(char v);
	void InsertEdge(char v1, char v2);
	void PrintGraph();
	int GetVertexIndex(char v);//获得邻接表顶点下标
	void DelVertex(char v);
	void DelEdge(char v1, char v2);
	void BFS(char v);
	void DFS(char v);
	void DFS(int v,bool*visted);//递归
private:
	int m_MaxVertex;//最多结点数
	int m_NumVertex;//当前结点数
	int m_NumEdge;//边数
	Vertex* m_VerArr;
};
void LinkGraph::BFS(char v)
{
	int p = GetVertexIndex(v);//获得队头元素的下标
	if (p == -1)//判断邻接顶点是否存在
		return ;
	bool* visited = new bool[m_NumVertex];//定义判断顶点是否被访问过的数组
	for (int i = 0; i < m_NumVertex; ++i)//遍历数组
	{
		visited[i] = false;//全部置为false,即未访问过
	}
	queue<int > qq;//定义队列
	qq.push(p);//队头元素入队
	cout << m_VerArr[p].m_value;//!!刚刚忘了写这句
	visited[p] = true;//遍历数组中被访问过置为true,即已被访问过
	cout << " ";
	int front;//队头顶点下标
	Edge* plist = nullptr;//指向队头元素的结构体指针
	while (!qq.empty())//判断队列是否为空
	{
		front = qq.front();//获取并保存队列的头的下标
		qq.pop();//头顶点出队
		plist = m_VerArr[front].m_list;//plist被赋值为根据下标找到所指向的顶点元素
		while (plist != nullptr)//判断是否有下一个邻接顶点
		{
			if (!visited[plist->m_index])//判断是否访问过,如果未被访问过则进入if语句
			{
				cout << m_VerArr[plist->m_index].m_value << " ";//打印元素
				visited[plist->m_index] = true;//判访问数组置为true
				qq.push(plist->m_index); //入队
			}
		plist = plist->m_next;
		}
	}
	cout << endl;
}
void LinkGraph::DFS(int v, bool* visited)
{
	cout << m_VerArr[v].m_value<<" ";
	visited[v] = true;
	Edge*p=m_VerArr[v].m_list;//邻接表指针
	while (p != nullptr)//保证邻接表里有东西
	{
		//从没有被访问过的邻接表里开始继续DFS
		if (!visited[p->m_index])//判断是否被访问过 
		{
			DFS(p->m_index,visited);
		}
		p = p->m_next;
	}

}
void LinkGraph::DFS(char v)
{
	int p = GetVertexIndex(v);//获取下标
	if (p == -1)
		return;
	bool* visited = new bool[m_NumEdge];//定义num个数的bool数组
	for (int i = 0; i < m_NumVertex; ++i)//置false
	{
		visited[i] = false;
	}
	DFS(p, visited);//递归调用+打印
	delete[] visited;
	visited = nullptr;
	cout << endl;
}

void LinkGraph::DelVertex(char v)
{
	int pindex = GetVertexIndex(v);
	if (pindex == -1)
		return;
	Edge* p = m_VerArr[pindex].m_list;
	char destvalue;
	while (p != nullptr)
	{
		destvalue = m_VerArr[p->m_index].m_value;//获得邻接顶点
		DelEdge(v, destvalue);
		p = m_VerArr[pindex].m_list;
	}
	//覆盖
	m_NumVertex--;
	m_VerArr[pindex].m_value = m_VerArr[m_NumVertex].m_value;
	m_VerArr[pindex].m_list = m_VerArr[m_NumVertex].m_list;
	//修改
	Edge* q = nullptr;
	p = m_VerArr[pindex].m_list;
	while (p != nullptr)
	{
		int k = p->m_index;
		q = m_VerArr[k].m_list; //找到相关联的顶点的边链表
		while (q)
		{
			if (q->m_index == m_NumVertex)
			{
				q->m_index = pindex;
				break;
			}
			q = q->m_next;
		}
		p = p->m_next;
	}

}
void LinkGraph::DelEdge(char v1, char v2)
{
	int p1 = GetVertexIndex(v1);
	int p2 = GetVertexIndex(v2);
	Edge* p = m_VerArr[p1].m_list;
	Edge* pf = nullptr;
	while (p != nullptr && p->m_index != p2)
	{
		pf = p;
		p = p->m_next;
	}
	if (p == nullptr)
		return;
	if (pf == nullptr)
	{
		m_VerArr[p1].m_list = p->m_next;
	}
	else
	{
		pf->m_next = p->m_next;
	}
	delete p;
	p = m_VerArr[p2].m_list;
	pf = nullptr;
	while (p != nullptr && p->m_index != p1)
	{
		pf = p;
		p = p->m_next;
	}
	if (p == nullptr)
		return;
	if (pf == nullptr)
		m_VerArr[p2].m_list = p->m_next;
	else
	{
		pf->m_next = p->m_next;
	}
	delete p;
	m_NumEdge--;
}
void LinkGraph::PrintGraph()
{
	int i;
	Edge* p = nullptr;
	for (i = 0; i < m_NumVertex; ++i)
	{
		cout << i << " " << m_VerArr[i].m_value << ":";
		p = m_VerArr[i].m_list;
		while (p)//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!11
		{
			cout << p->m_index << "->";
			p = p->m_next;
		}
		cout << "nul" << endl;
	}
}
void LinkGraph::InsertVertex(char v)
{
	if (m_NumVertex >= m_MaxVertex)
	{
		return;
	}
	m_VerArr[m_NumVertex].m_value = v;
	char w = m_VerArr[m_NumVertex].m_value;///
	m_NumVertex++;
}
int LinkGraph::GetVertexIndex(char v)
{
	for (int i = 0; i < m_NumVertex; i++)
	{
		char w = m_VerArr[i].m_value;
		if (v == w)
		{
			return i;
		}
	}
	return -1;
}
void LinkGraph::InsertEdge(char v1, char v2)
{
	int p1 = GetVertexIndex(v1);
	int p2 = GetVertexIndex(v2);
	if (p1 == -1 || p2 == -1)
		return;
	Edge* edge = new Edge(p1);
	edge->m_next = m_VerArr[p2].m_list;
	m_VerArr[p2].m_list = edge;
	edge = new Edge(p2);
	edge->m_next = m_VerArr[p1].m_list;
	m_VerArr[p1].m_list = edge;
	m_NumEdge++;

}
int main()
{
	LinkGraph lg;
	{
		lg.InsertVertex('A');
		lg.InsertVertex('B');
		lg.InsertVertex('C');
		lg.InsertVertex('D');
		lg.InsertVertex('E');
		lg.InsertVertex('F');
		lg.InsertVertex('G');
		lg.InsertVertex('H');
		lg.InsertVertex('I');
		lg.InsertEdge('A', 'B');
		lg.InsertEdge('A', 'F');
		lg.InsertEdge('B', 'I');
		lg.InsertEdge('B', 'C');
		lg.InsertEdge('B', 'G');
		lg.InsertEdge('C', 'D');
		lg.InsertEdge('C', 'I');
		lg.InsertEdge('D', 'I');
		lg.InsertEdge('D', 'G');
		lg.InsertEdge('D', 'H');
		lg.InsertEdge('D', 'E');
		lg.InsertEdge('E', 'H');
		lg.InsertEdge('E', 'F');
		lg.InsertEdge('F', 'G');
		lg.InsertEdge('G', 'H');
	}
	lg.PrintGraph();
	lg.BFS('A'); 
	lg.DFS('A');
	
	return 0;
}

 遍历运行结果

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值