图的DFS非递归实现,栈
思路
- 第一个结点入栈,读栈顶,结点有未被访问的邻接点则将邻接点入栈,再读栈顶(不出栈),栈顶元素有未被访问的边则继续入栈
- 若读到的栈顶没有边或者都被访问过,则出栈,然后再读下一个栈顶(看下一栈顶是否有未被访问的边)
图如下
从结点 6 开始DFS遍历
代码
//图邻接表结构的定义
typedef struct ANode{
int adjvex;
int weight; //权
struct ANode *nextarc;
}ArcNode;
typedef struct VNode{
int data;
ArcNode *firstarc;
}VNode;
typedef struct{
VNode adjlist[MAXV];
int n,e;
}AdjGragh;
int visited[MAXV]={0};
VNode stack[MAXV]; //结点栈
int top=-1; //栈顶指针
void DFS(AdjGragh *&G)
{
VNode vnode=G->adjlist[6]; //从第七个节点开始DFS
visited[vnode.data]=1; //标记访问
cout<<vnode.data<<" ";
stack[++top]=vnode; //入栈
while(top!=-1) //栈不空循环
{
vnode=stack[top]; //读栈顶
ArcNode *node=vnode.firstarc; //读结点的边
int flag=0; //标志位表示是否找到未被访问的边(结点)
while(node!=NULL) //寻找邻接点
{
if(visited[node->adjvex]!=1){ //如果未被访问
stack[++top]=G->adjlist[node->adjvex]; //将这个点入栈
visited[node->adjvex]=1; //标记访问
cout<<node->adjvex<<" ";
flag=1;
break;
}
node=node->nextarc; //若被访问过则找下一边
}
if(flag==0) //如果flag为0,则需要出栈,否则直接进行下一轮读栈顶
top--;
}
}
运行结果
图的邻接矩阵表示
//用矩阵表示图
int A[MAXV][MAXV]={
{0,1,0,0,0,0,0,0},
{0,0,0,1,0,0,0,0},
{0,0,0,0,0,1,0,0},
{0,0,0,0,0,0,0,1},
{0,0,0,1,0,0,1,0},
{0,0,0,0,1,0,0,1},
{1,0,1,0,0,0,0,0},
{0,1,0,0,0,0,0,0}
};