存储结构:
ArcNode 边表节点数据结构(包含索引值vertex和next)
VertexNode 顶点表节点数据结构(包含顶点数据和第一个边表节点firstEnde)
adjlist[] 顶点表节点数组
vertexNum 顶点数
arcNum 边数
visited[] 标志数组
功能:
1.构建基于邻接表的无向图
2.深度优先遍历
3.广度优先遍历
伪代码:
构建
1.标志数组初始化
2.顶点表节点数组初始化赋值
3.重复arcNum次下列操作
3.1 输入边的两顶点
3.2 new一个边表节点i,j
3.3 将索引值赋为j
3.4 将该节点用头插法插入i的链表
3.5 i,j互换,重复上述操作
深度遍历
1.输出一个顶点v的数据并将v的firstEdge赋给p
2.重复下列操作直到p==NULL
2.1 将p的索引值赋给j
2.2 如果该索引值对应的顶点节点未被访问深度遍历j
2.3 p指向p->next
广度遍历
1.初始化visited数组
2.重复下列操作vertexNum次
2.1 初始化队列
2.2 输出该顶点数据并将其入队
2.3 当队列不为空时重复下列操作
2.3.1 队首出队(++front)并赋给i
2.3.2 将i对应的顶点的firstEdge赋给p
2.3.3 重复下列擦欧洲哦直到p==NULL
2.3.3.1 获得p的下标
2.3.3.2 如果p的下标对应的顶点未被访问输出该顶点数据并标志其已访问,并将其入队
2.3.3.3 p=p->next;
#include<iostream>
using namespace std;
#define MaxSize 100
//边表节点
struct ArcNode
{
int adjvex; //下标,索引值
ArcNode *next; //指向下一个边表节点
};
//顶点表表节点(最开始的那批数据)
template<class T>
struct VertexNode
{
T vertexData; //顶点数据
ArcNode *firstEdge; //指向第一个边表节点
};
/**基于邻接表的无向图*/
template<class T>
class ALGraph
{
private:
void DFS(int v);
public:
ALGraph();
~ALGraph() {}
void DFSTraverse();
void BFSTraverse();
private:
VertexNode<T> adjlist[MaxSize]; //储存顶点表节点的数组
int VertexNum,arcNum;
int visited[MaxSize];
};
template<class T>
ALGraph<T>::ALGraph()
{
int i,j,k;
cout<<"依次输入顶点数n、边数e、及n个顶点的编号和顶点之间的连通关系的两个顶点的编号:"<<endl;
cin>>VertexNum;
cin>>arcNum;
//把标志数组初始化
//虽然两个遍历都会初始化,但是先行初始化总是好的,避免还未遍历便要用vidited的情况
for(i=0; i<MaxSize; i++)
visited[i]=0;
//顶点数据赋值
for(i=0; i<VertexNum; i++)
{
cin>>adjlist[i].vertexData;
adjlist[i].firstEdge=NULL;
}
//边关系
for(k=0; k<arcNum; k++)
{
cin>>i>>j;
ArcNode *s1=new ArcNode;
s1->adjvex=j;
s1->next=adjlist[i].firstEdge;
adjlist[i].firstEdge=s1;
ArcNode *s2=new ArcNode;
s2->adjvex=i;
s2->next=adjlist[j].firstEdge;
adjlist[j].firstEdge=s2;
}
}
template<class T>
void ALGraph<T>::DFS(int v)
{
int j;
ArcNode *p;
cout<<adjlist[v].vertexData<<' ';
visited[v]=1;
p=adjlist[v].firstEdge;
while(p!=NULL) //依次搜索各个邻接点
{
j=p->adjvex;
if(visited[j]==0)
DFS(j); //中途抢占,深度遍历
p=p->next;
}
}
template<class T>
void ALGraph<T>::DFSTraverse()
{
int i,v;
//标记数组初始化
for(i=0; i<MaxSize; i++)
visited[i]=0;
cout<<"深度优先遍历的结果为:";
for(i=0; i<VertexNum; i++) //直接从头开始一个顶点一个顶点的遍历,虽然好像有点流氓
{
v=adjlist[i].vertexData;
if(!visited[v])
{
DFS(v);
}
}
cout<<endl;
}
template<class T>
void ALGraph<T>::BFSTraverse()
{
int front,rear,i,j,v;
int Q[MaxSize];
ArcNode *p;
//把标志数组初始化
for(i=0; i<MaxSize; i++)
visited[i]=0;
cout<<"广度优先遍历的结果为:";
for(i=0; i<VertexNum; i++) //直接从头开始一个顶点一个顶点的遍历,虽然好像有点流氓
{
v=adjlist[i].vertexData;
if(visited[v]==0)
{
front=rear=-1;
cout<<adjlist[i].vertexData<<' ';
visited[v]=1;
Q[++rear]=v; //下标入队
while(front!=rear) //队列不空,循环
{
v=Q[++front];
p=adjlist[v].firstEdge;
while(p!=NULL)
{
j=p->adjvex; //获得下标
if(visited[j]==0)
{
cout<<adjlist[j].vertexData<<' ';
visited[j]=1;
Q[++rear]=j;
}
p=p->next;
}
}
}
}
cout<<endl;
}
int main()
{
int n,e,i;
int a[MaxSize];
ALGraph<int> G;
G.DFSTraverse();
G.BFSTraverse();
return 0;
}
测试数据:
输入:
6 5
0 1 2 3 4 5
0 1
0 3
1 2
2 3
4 5
输出:
深度优先遍历的结果为:0 3 2 1 4 5
广度优先遍历的结果为:0 3 1 2 4 5
该图为数据的图示