一、同7.22题要求。试基于图的广度优先搜索策略写一算法。
答:
本题需要以邻接表的方式来实现BFS算法从而判断是否存在从一点到另一点的路径。由所学知识可以知道,实现BFS可以队列的方式。在这道题,使用队列的方式进行实现。
该算法实现的伪代码如下:
/* 函数名称:给定图中,判断给定两点之间是否存在路径 传入参数:图G,起点start,终点end 返回值:bool型 如果有返回true,否则返回false */ int visit[MAXSIZE]; int number = 0; bool BFS(Graph G, int start, int end) { for(int i = 1; i <= G.Vexnum; ++i) { visit[i] = false; } visit[start] = true; InitQueue(&Q); //创建队列 EnQueue(&Q, start); //将起点放入队列 while(!QueueEmpty(Q)) { //如果队列不为空 //取出队首元素 DeQueue(&Q, &e); for(EdgeNode* temp = G.adjlist[start].firstedge; temp; temp = temp -> next) { if(!visit[temp -> adjVexIndex]) { visit[temp -> adjVexIndex] = true; if(temp -> adjVexIndex == j) { return true; } } EnQueue(&Q, temp -> adjVexIndex); } } //如果没有找到 return false; } |
算法分析:由所学知识,与上题类似。我们能很容易知道BFS的时间复杂度也为O(n+e),与DFS一样。如果直接使用暴力搜索的话,会造成巨大的时间开销。综上,这是解决该问题的较好的方法。
二、采用邻接表存储结构,编写一个判别无向图中任意给定的两个顶点之间是否存在一条长度为k的简单路径的算法。
答:
本题与上题的解法十分类似,不同点在于需要多传入一个参数k,从而进行长度的判断。同时visit数组应当定义为int类型从而可以更好地实现重复访问和判断第几次访问到这个点。其余方法与上题类似。
该算法实现的伪代码如下:
/* 函数名称:给定图中,判断给定两点之间是否存在长度为k路径 传入参数:图G,起点start,终点end,路径长度k 返回值:bool型 如果有返回true,否则返回false */ int visit[MAXSIZE]; int number = 0; bool DFS(Graph G, int start, int end, int k) { EdgeNode *temp; //如果找到了路径返回真 visit[start] = number++; //判断是第几次访问到 if(start == end && k == 0) { return true; } else if(k > 0) { temp = G.adjlist[start].firstedge; //得到与起始点相连的边 while(p) { int index = p -> adjVexIndex; //获得该边对应的标号 if(!visited[index]) { //利用递归的方式继续进行寻找 if(DFS(G, index, end, k)) { return true; //如果从邻边中找到 } else{ //否则退一步 visited[p -> adjV] = false; number--; }
} p = p -> next; } } return false; //如果找到最后也没找到证明没有长度为k的路径 } |
算法分析:由所学知识,与上题类似。我们能很容易知道DFS的时间复杂度为O(n+e)。如果直接使用暴力搜索的话,会造成巨大的时间开销。综上,这是解决该问题的较好的方法。