学习邻接表存图请看:https://blog.csdn.net/HPU_FRDHR/article/details/83957240
DFS (深度优先搜索)
深度优先搜索算法(英语:Depth-First-Search,简称DFS)是一种用于遍历或搜索树或图的算法。 沿着树的深度遍历树的节点,尽可能深的搜索树的分支。当节点v的所在边都己被探寻过或者在搜寻时结点不满足条件,搜索将回溯到发现节点v的那条边的起始节点。整个进程反复进行直到所有节点都被访问为止。属于盲目搜索,最糟糕的情况算法时间复杂度为O(!n)。
算法步骤:
按如下将图存好后开始遍历:
1.在访问图中某一起始顶点 v 后,由 v 出发,访问它的任一邻接顶点 w1;
2.再从 w1 出发,访问与 w1邻接但还未被访问过的顶点 w2;
3.然后再从 w2 出发,进行类似的访问,…,如果w2后所有的节点都被访问过了,接着,退回一步,退到前一次刚访问过的顶点,看是否还有其它没有被访问的邻接顶点,即回溯到前一个节点w1继续访问。
4.如此进行下去,直至到达所有的邻接顶点都被访问过的顶点 u 为止。
代码实现:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
using namespace std;
#define OK 1
#define MVNum 100 //最大顶点数
typedef int Status;
typedef int OtherInfo;
typedef char VerTexType;
Status visited[MVNum]; //访问标志数组,其初值为0
typedef struct ArcNode{ //边节点
int adjvex; //该边所指向的在顶点的位置
struct ArcNode * nextarc; //指向下一条边的指针
OtherInfo info; //和边相关的信息
}ArcNode;
typedef struct Vnode{ //顶点信息
VerTexType data;
ArcNode *firstarc; //指向第一条依附该顶点的指针
}VNode,AdjList[MVNum]; //AdjList表示邻接表类型
typedef struct{
AdjList vertices;
int vexnum,arcnum; //图当前的顶点数和边数
}ALGraph;
//确定v在G中的位置,即顶点在G.vertices中的序号
Status LocateVex(ALGraph G,char v){
int i;
for(i=0;i<G.vexnum;i++){
if(v==G.vertices[i].data)
return i;
}
}
//邻接表法创建无向图
Status CreateUDG(ALGraph &G){
Status i,j,k;
char v1,v2;
ArcNode *p1,*p2;
cout<<"请输入总顶点数 总边数:";
cin>>G.vexnum>>G.arcnum; //输入总顶点数总边数
puts("请输入顶点信息:");
for(i=0;i<G.vexnum;++i){ //输入各点,构造表头节点表
cin>>G.vertices[i].data; //输入顶点值
G.vertices[i].firstarc=NULL; //初始化表头节点的指针域为NULL
}
puts("请输入每一条边对应的两个顶点:");
for(k=0;k<G.arcnum;++k){ //输入各边,构造邻接表
cin>>v1>>v2; //输入一条边依附的两个顶点
i=LocateVex(G,v1);
j=LocateVex(G,v2);
p1=new ArcNode; //生成一个新的边节点*p1
p1->adjvex=j; //邻接点序号为j
p1->nextarc=G.vertices[i].firstarc; //将新节点*p1插入顶点vi的边表头
G.vertices[i].firstarc=p1;
p2=new ArcNode; //生成一个新的边节点*p2
p2->adjvex=i; //邻接点序号为i
p2->nextarc=G.vertices[j].firstarc; //将新节点*p2插入顶点vj的边表头
G.vertices[j].firstarc=p2;
}
return OK;
}
//打印邻接表存储数据
void print_position(ALGraph G){
int i;
for(i=0;i<G.vexnum;i++){
ArcNode p;
p.adjvex=G.vertices[i].firstarc->adjvex;
p.nextarc=G.vertices[i].firstarc->nextarc;
printf("%c->",G.vertices[i].data);
while(p.nextarc!=NULL){
printf("%c -> ",G.vertices[p.adjvex].data);
p=*p.nextarc;
}
printf("%c\n",G.vertices[p.adjvex].data);
}
}
//递归实现从第v个顶点出发深度优先搜索遍历图G
void DFS_AL(ALGraph G,int v){
ArcNode *p;
int w;
printf("%c ",G.vertices[v].data); //访问第v个顶点
visited[v]=1; //置访问标志数组相应分量值为1
p=G.vertices[v] .firstarc; //p指向v的边链表的第一个边结点
while (p!=NULL){ //边结点非空
w=p->adjvex; //表示w是V的邻接点
if(!visited[w]) DFS_AL(G,w); //如果w未访问,则递归调用DFS_ AL
p=p->nextarc; //p指向下一个边结点
}
}
//非递归实现从第v个顶点出发深度优先搜索遍历图G
void DFS_ALL(ALGraph G,int v){
memset(visited,0,sizeof(visited));
stack<char> st; //定义一个栈
ArcNode *p;
int w,n,s;
n=G.vexnum-1;
printf("%c ",G.vertices[v].data); //访问第v个顶点
st.push(G.vertices[v].data); //将第v个顶点压入栈中
visited[v]=1; //置访问标志数组相应分量值为1
p=G.vertices[v] .firstarc; //p指向v的边链表的第一个边结点
while(n){
int cnt=0;
while(p!=NULL){ //边结点非空
w=p->adjvex; //表示w是V的邻接点
if(!visited[w]){//如果w未访问
printf("%c ",G.vertices[w].data);
st.push(G.vertices[w].data);
visited[w]=1;
cnt=1,n--;
break;
}else
p=p->nextarc;
}
if(cnt==0)
st.pop();
s=LocateVex(G,st.top());
p=G.vertices[s] .firstarc;
}
}
int main(){
char s,k;
int n,m;
memset(visited,0,sizeof(visited));
ALGraph G;
CreateUDG(G);
puts("构建的邻接表为:");
print_position(G);
puts("请输入递归遍历开始的起点:");
cin>>s;
n=LocateVex(G,s);
DFS_ALL(G,n);
printf("\n");
puts("请输入非递归遍历开始的起点:");
cin>>k;
m=LocateVex(G,k);
DFS_ALL(G,m);
return 0;
}