数据结构学习笔记 图:深度优先搜索(严蔚敏版)

来源:互联网 发布:淘宝店开了一年没生意 编辑:程序博客网 时间:2024/06/03 13:38

深度优先搜索:假设初始状态是图中的所有顶点未曾被访问,则深度优先搜索可从图中某个顶点v出发,访问此顶点,然后依次从v的未被访问的邻接点出发深度优先遍历图,直至图中的所有和v有路径相通的顶点都被访问到;若此时图中尚有顶点未被访问,则另选图中一个未曾被访问的顶点作起始点,重复上述过程,直至图中的所有顶点都被访问到为止。

       邻接表存储结构分为两部份:一是顺序表,二是链表。图中的顶点按顺序存储在顺序表中,顺序表结点分为两个域:数据域(data)和链域(firstarc),数据域存储的是图中顶点的信息,链域存储的是指针,指向该点的其中一个邻接点;在链表中存储的是顶点vi的邻接点,链表中分为邻接点域(adjvex)、链域(nextarc)和数据域(info),邻接点域(adjvex)存储的是顶点vi的邻接点在顺序表中的位置,链域(firstarc)指向顶点vi下一个邻接点,数据域存储的是网的权值。

       如果图是用邻接表存储结构存储,那么在进行深度优先搜索遍历时,先从顺序表中的第一个顶点vi出发,访问该顶点(记得别忘了将已访问过的顶点做标记),然后访问vi在存储结构中的第一个邻接点vj,接着再访问vj的邻接点,不断的进行“访问邻接点的邻接点”这样一个循环,直到遇到一个顶点它的邻接点已经被访问过,循环结束,接着访问vi的下一个邻接点,直至vi的邻接点都被访问完。访问完vi的邻接点后,接着访问顺序表中的第二个顶点,直至顺序表中的所有顶点都已经被访问到。

顺序表中的结点:

链表中的结点:

 

图:


邻接表:


#include<iostream>               ///深度优先搜索,通过有向图的邻接表存储#include<malloc.h>               ///有向图的邻接表中,第i个链表的的结点数只是顶点vi的出度,为求入度,必须遍历整个邻接表或是建立有向图的逆邻接表#define MAX_VERTEX_NUM 20#define MAX_NAME 5#define OK 1#define TRUE 1#define FALSE -1typedef char VertexType[MAX_NAME];    typedef int InfoType;       using std::cin;using std::cout;using std::endl;typedef struct ArcNode                           //单链表中结点的类型{int adjvex;                              //该边指向的顶点在顺序表中的位置struct ArcNode *nextarc;  InfoType *info;                          //网的权值指针}ArcNode;typedef struct VNode                             //定义顶点类型{VertexType data;ArcNode *firstarc; }VNode, AdjList[MAX_VERTEX_NUM];typedef struct      {AdjList vertices;                        //顺序表int vexnum, arcnum;    int kind;}ALGraph;int LocateVex(ALGraph &G, VertexType &u)         //返回顶点u在vertices中的位置{   for(int i = 0;i < G.vexnum; ++i)   {   if(strcmp(G.vertices[i].data,u) == 0)   return i;   }   return FALSE ;}int CreateDG( ALGraph &G )                       //有向图的邻接表{   int  i,j,k,w;  VertexType v1,v2;   cout <<"开始构造有向图:\n请输入图的顶点的个数:";cin >> G.vexnum;cout << "请输入图的边的数目:";cin >> G.arcnum;  cout <<"请输入所有的顶点:\n";  for(i = 0; i < G.vexnum; ++i){        cout << "请输入第"<< i+1 << "个顶点:";scanf("%s",G.vertices[i].data);G.vertices[i].firstarc = NULL;}  cout <<"请输入弧,例如 v1-->v2\n";  for(k = 0; k < G.arcnum; ++k){           cout << "请输入第" << k+1 << "条弧的弧尾";   cin >> v1;   cout << "请输入第" << k+1 << "条弧的弧头";   cin >> v2;           i = LocateVex(G,v1);   j = LocateVex(G,v2);   ArcNode *p;   p = (ArcNode *)malloc(sizeof(ArcNode));   if(!p)   {   cout << "Overflow";   return 0;   }   p->adjvex = j;   p->nextarc = G.vertices[i].firstarc;       //单链表的逆序构造,即输入的第一个结点会成为最后一个结点   G.vertices[i].firstarc  = p;   p->info = NULL;}   // for end            return OK;}  // CreateDG() endvoid DFS(ALGraph G, int v, int *visited)              //如果该图是连通图,只需从G.vertices[0]出发便可以遍历图中的所有节点{                                                             ArcNode *p;int w;visited[v] = TRUE;cout << v + 1 << "->";for(p = G.vertices[v].firstarc; p != NULL; p = p->nextarc){if(visited[p->adjvex] == 0){visited[p->adjvex] = 0;DFS(G, p->adjvex,visited);   //不断的访问节点的邻接点}}       }  // DFS() endvoid DFSTraverse( ALGraph &G ){int v;int visited[MAX_VERTEX_NUM];for( v = 0; v < G.vexnum; ++v )visited[v] = 0;                       //visited 为辅助数组用于标记顶点是否被访问for( v = 0; v < G.vexnum; ++v )if(visited[v] == 0 )DFS(G,v,visited); }//DFSTraverse() endvoid DestroyALGraph(ALGraph &G)                      //销毁分配的空间{    ArcNode *q;    for(int i = 0; i < G.vexnum; ++i)    for(ArcNode *p = G.vertices[i].firstarc; p != NULL;)    {      G.vertices[i].firstarc = NULL;      q = p;              p = p->nextarc;              free(q);          }}void main(){ALGraph G;cout << endl << "DFSTraverse.cpp";cout << endl << "===================" << endl;CreateDG(G);   cout <<"深度优先搜索:\n";DFSTraverse(G);        DestroyALGraph(G);}// main end

运行结果:


0 0