//图的存储结构
//边,弧
typedef struct ArcNode{
int adjvex;//边/弧指向哪一个结点
struct ArcNode *next;//指向下一条弧的指针
}ArcNode;
//顶点
typedef struct VNode{
VertexType data;//顶点信息
ArcNode *first;//第一条边/弧
struct ArcNode *next;//指向下一条弧的指针
}VNode,AdjList[MaxVertexNum];
//用邻接表存储的图
typedef struct{
AdjList vertices;//顶点信息
int vexnum,arcnum;//总顶点数,总边数
}ALGraph;
//图的广度优先遍历
bool visited[MAX_VERTEX_NUM];//访问标记数组
void BFSTraverse(Graph G){
for(i = 0;i<G.vernum;++i)//对标记数组初始化
visited[i] = false;
InitQueue(Q);
for(i = 0;i<G.vernum;++i)
if(!visited[i])//对每一个连通分量调用一次BFS
BFS(G,i); //vi未 访问过,从vi开始BFS
}
//广度优先遍历图 ,如果只用这个函数,对于非连通图则无法对全部顶点的遍历 ,所以要从BFSTraverse(Graph G) 函数调用BFS
void BFS(Graph G,int v){
visit(v);//也可以简单写成cout<<v,访问第v个顶点
visited[v] = true;
Enqueue(Q,v);
while(!isEmpty(Q)){
DeQueue(Q,v);
for(w = FirstNeighbor(G,v);w>=0;w=NextNeighbor(G,v,w)){
//检测v所有的邻接点
if(!visited[w]){
visit(w);
visited[w] = true;
EnQueue(Q,w);//
}//if
}//for
}//while
}
//FirstNeighbor(G,v),返回顶点v的第一个邻接点,没有则返回-1
// NextNeighbor(G,v,w),返回以v为根的除了邻接点w外的另一个邻接点 ,没有则返回-1
//图的深度遍历和二叉树前序遍历类似
//图的深度遍历递归遍历
bool visited[MAX_VERTEX_NUM];//访问标记数组
void DFSTraverse(Graph G){
for(i = 0;i<G.vernum;++i)//对标记数组初始化
visited[i] = false;
//InitQueue(Q);
for(i = 0;i<G.vernum;++i)
if(!visited[i])//对每一个连通分量调用一次BFS
DFS(G,i); //vi未 访问过,从vi开始DFS
}
void DFS(Graph G,int v){
visit(v);//访问顶点
visited[v] = true;
for(w=FirstNeighbor(G,v));w>=0;w=NextNeighbor(G,v,w))
if(!visit[w]){
DFS(G,w);
}
}
//图的深度优先非递归遍历
void DFS_Non_Rc(Graph G,int v){
int w;//存储当前访问节点的临时变量
InitStack(S);
for(i = 0;i<G.vexnum;i++)
visited[i] = false;
Push(S,v);//顶点v入栈
visited[v]=true;
while(!isEmpty(S)){
k = pop(S);
visit(k);//对顶点k进行访问
for(w = FirstNeighbor(G,v);w>=0;w=NextNeighbor(G,v,w)){
if(!visited[w]{
Push(S,w);
visited[w] = true;
//将结点1的全部邻接点入栈之后的情况如图所示,节点1出栈,将节点3出栈并将节点3的全部邻接点入栈以此类推,所以最后的遍历顺序为 1 3 4 2 5 有一种从右往左的感觉
}//if
}//for
}//while
}