用邻接表实现图:
(先放上总代码吧,仔细看也不多的😁)
#include <iostream>
#include <queue>
using namespace std;
const int MaxSize = 10; //图的最大顶点数
bool visited[10] = {0,0,0,0,0,0,0,0,0,0};
struct ArcNode //边表
{
int adjvex; //邻接点域,存储该顶点对应的下标
struct ArcNode *next;
};
struct VertexNode //顶点表V0,V1,V2,V3...
{
int vertex; /* 顶点域,储存顶点信息 */
struct ArcNode *firstedge; //指向边表的头指针
};
template <class DataType>
class ALGraph
{
public:
ALGraph(DataType a[], int n, int e);
void Output();
void DFS(int v);
void BFS();
void DFSTraverse();
private:
VertexNode adjlist[MaxSize];//顶点表数组V0,V1,V2,V3...
int vertexNum, edgeNum; //图中的顶点数与边数
};
/** 构造函数
*@param n 顶点数
*@param e 边数
*/
template <class DataType>
ALGraph<DataType> :: ALGraph(DataType a[], int n, int e)
{ int i,j,k;
vertexNum = n; edgeNum = e;
for (i = 0; i < vertexNum; i++)//赋顶点表数组V0,V1,V2,V3...的值(0,1,2,3),并指向NULL成为空表
{ //输入顶点信息,初始化顶点表
adjlist[i].vertex = a[i];
adjlist[i].firstedge = NULL;
}
for (k = 0; k < edgeNum; k++) //输入边的信息存储在边表中
{
cin>>i>>j;
ArcNode *s; //指向边表的指针
s = new ArcNode; //new一个节点
s->adjvex = j; //邻接序号为j
s->next = adjlist[i].firstedge;
adjlist[i].firstedge = s;
/*两份类似代码是为了形成无向图,去掉是有向图 */
ArcNode *p; //指向边表的指针
p = new ArcNode; //new一个节点
p->adjvex = i; //邻接序号为j
p->next = adjlist[j].firstedge;
adjlist[j].firstedge = p;
}
}
template <class DataType>
void ALGraph<DataType> :: Output()
{
int i,j;
for (i = 0; i < vertexNum; i++){ //输出邻接表
cout << "与顶点"<< i <<"相邻的顶点:"<< endl;
ArcNode *p;
p = new ArcNode;
p = adjlist[i].firstedge; //工作指针p指向顶点i的边表
while (p != NULL) //依次输出顶点i的邻接点j
{
j = p->adjvex;
cout << j << " ";
p = p->next;
}
cout << endl;
}
}
template <class DataType>
void ALGraph<DataType> :: DFS(int v)
{
ArcNode *p; //边表指针
visited[v] = true;
cout<<adjlist[v].vertex<<" ";//利用顶点表打印顶点
p = adjlist[v].firstedge;
while(p){
if(!visited[p->adjvex])
DFS(p->adjvex);//传入边表的值-->再到顶点表里面找对应位置
p=p->next;
}
}
//邻接表的深度遍历操作
template <class DataType>
void ALGraph<DataType> :: DFSTraverse()
{
int i;
for(i=0; i<vertexNum; i++){//i小于顶点数
visited[i] = false; //初始化所有顶点都是未访问状态
}
for(i=0; i<vertexNum; i++){
if(!visited[i])/*对未访问过的顶点调用DFS,若是连通图,只会执行一次 */
DFS(i);
}
}
template <class DataType>
void ALGraph<DataType> :: BFS()/*从0开始BFS遍历*/
{
int i;
ArcNode *p; //边表指针
queue<int> Q;//初始化顺序队列
for(i=0; i<vertexNum; i++)
visited[i] = false;
for(i=0; i<vertexNum; i++){
if(!visited[i]){
visited[i] = true;
cout<<adjlist[i].vertex<<" ";//打印顶点
Q.push(i);//i入队列
while(!Q.empty())
{
Q.pop();
p = adjlist[i].firstedge;//找到当前顶点表边表链表的头指针
while(p){
if(!visited[p->adjvex]){//顶点没有被访问
visited[p->adjvex] = true;
cout << adjlist[p->adjvex].vertex <<" ";//输出顶点表的对应的下标
Q.push(p->adjvex);//将此顶点入队列
}
p=p->next;
}
}
}
}
}
int main()
{
int a[5]={0,1,2,3};
ALGraph<int> g(a,4,4);
g.Output();
cout<<"-------"<<endl;
g.DFS(2);
cout<<"\n-------"<<endl;
g.BFS();
return 0;
}
分析一下构造函数
/** 构造函数
*@param n 顶点数
*@param e 边数
*/
template <class DataType>
ALGraph<DataType> :: ALGraph(DataType a[], int n, int e)
{ int i,j,k;
vertexNum = n; edgeNum = e;
for (i = 0; i < vertexNum; i++)//赋顶点表数组V0,V1,V2,V3...的值(0,1,2,3),并指向NULL成为空表
{ //输入顶点信息,初始化顶点表
adjlist[i].vertex = a[i];
adjlist[i].firstedge = NULL;
}
for (k = 0; k < edgeNum; k++) //输入边的信息存储在边表中
{
cin>>i>>j;
ArcNode *s; //指向边表的指针
s = new ArcNode; //new一个节点
s->adjvex = j; //邻接序号为j
s->next = adjlist[i].firstedge;
adjlist[i].firstedge = s;
/*两份类似代码是为了形成无向图,去掉是有向图 */
ArcNode *p; //指向边表的指针
p = new ArcNode; //new一个节点
p->adjvex = i; //邻接序号为j
p->next = adjlist[j].firstedge;
adjlist[j].firstedge = p;
}
}
图片分析
第一步:输入0,1
第二步:输入0,2
测试的总图
数据
/*
0 1
0 2
2 1
2 3
与顶点0相邻的顶点:
2 1
与顶点1相邻的顶点:
2 0
与顶点2相邻的顶点:
3 1 0
与顶点3相邻的顶点:
2
-----
2 3 1 0
*/
下面是重复的
下面是DFS深度遍历操作的代码
template <class DataType>
void ALGraph<DataType> :: DFS(int v)
{
ArcNode *p; //边表指针
visited[v] = true;
cout<<adjlist[v].vertex<<" ";//利用顶点表打印顶点
p = adjlist[v].firstedge;
while(p){
if(!visited[p->adjvex])
DFS(p->adjvex);//传入边表的值-->再到顶点表里面找对应位置
p=p->next;
}
}
//邻接表的深度遍历操作
template <class DataType>
void ALGraph<DataType> :: DFSTraverse()
{
int i;
for(i=0; i<vertexNum; i++){//i小于顶点数
visited[i] = false; //初始化所有顶点都是未访问状态
}
for(i=0; i<vertexNum; i++){
if(!visited[i])/*对未访问过的顶点调用DFS,若是连通图,只会执行一次 */
DFS(i);
}
}
BFS代码
template <class DataType>
void ALGraph<DataType> :: BFS()/*从0开始BFS遍历*/
{
int i;
ArcNode *p; //边表指针
queue<int> Q;//初始化顺序队列
for(i=0; i<vertexNum; i++)
visited[i] = false;
for(i=0; i<vertexNum; i++){
if(!visited[i]){
visited[i] = true;
cout<<adjlist[i].vertex<<" ";//打印顶点
Q.push(i);//i入队列
while(!Q.empty())
{
Q.pop();
p = adjlist[i].firstedge;//找到当前顶点表边表链表的头指针
while(p){
if(!visited[p->adjvex]){//顶点没有被访问
visited[p->adjvex] = true;
cout << adjlist[p->adjvex].vertex <<" ";//输出顶点表的对应的下标
Q.push(p->adjvex);//将此顶点入队列
}
p=p->next;
}
}
}
}
}