备注:顶点类、边类、主函数及其打印函数,查找顶点下标函数所有函数集合!!
遍历要求:
图从某一顶点出发,把每一个顶点访问有且只有一次
邻接表如下:
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,没有被访问过就设为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;
}