‘壹’ 已知有向图的邻接表存储结构如下图所示
深度优先是从某个顶点出发,访问完后,寻找一个未访问的邻接顶点继续深度优先,如果此路不同就往回退,所以看邻接表,首先访问V1,完了后顺链寻找没有访问的邻接顶点,自然链表中的第一个结点就是v3,接着转到v3再来深度优先,访问v3后,在其链表中第一个邻接顶点是v4
接着访问v4,下面走不通,回到v3,继续顺链往后,自然是v5,v5的邻接顶点中v2还没有访问
所以序列为v1, v3, v4, v5, v2
再看广度优先,从某个顶点完成后,需要一口气将其邻接未访问的所有顶点都访问,后面类推
于是过程是先v1,再顺链将v3,v2依次访问完,然后再依次访问v3和v2的各个未访问邻接顶点,v3链表中顺链可以访问v4,v5,所以最后访问序列为v1, v3, v2, v4, v5
‘贰’ 求算法!!用传递闭包来操作 BFS判断邻接表存储有向图G中顶点i到顶点j是否有路径
int exist_path_BFS(AdjGraph G,int i,int j)//广度优先判断有向图G中顶点i到顶点j是否有路径,是则返回1,否则返回0 { int visited[MAXSIZE]; InitQueue(Q); EnQueue(Q,i); while(!QueueEmpty(Q)) //队列不空时循环 { DeQueue(Q,u); visited=1; for(p=G.vertices[i].firstarc;p;p=p->nextarc) { k=p->adjvex; if(k==j) return 1; if(!visited[k]) EnQueue(Q,k); }//for }//while return 0; }//exist_path_BFS 这个是普通实现,求传递闭包的解法,谢谢
‘叁’ 判断用邻接表存储的有向图G是否存在回路的算法,答案给的这个看不懂,哪位大佬给注释一下
因此要在多个邻接顶点之间约定一种访问次序。@由于图中可能存在回路,在访问某个顶点之后,可能沿着某条路径又回到图的深度优先搜索遍历算法p88 联通的无回路的无向图,简称树。树中的悬挂点又成为树叶,其他顶点称为分支点
‘肆’ 编写一个程序,判别以邻接表方式的存储有向图G中是否存在由顶点Vi到顶点Vj的路径(i!=j)
int visited[MAXSIZE]; //指示顶点是否在当前路径上
int exist_path_DFS(ALGraph G,int i,int j)//深度优先判断有向图G中顶点i到顶点j是否有路径,是则返回1,否则返回0
{
if(i==j) return 1; //i就是j
else
{
visited[i]=1;
for(p=G.vertices[i].firstarc;p;p=p->nextarc)
{
k=p->adjvex;
if(!visited[k]&&exist_path(k,j)) return 1;//i下游的顶点到j有路径
}//for
}//else
}//exist_path_DFS
void find(int A[][],int m,int n)//求矩阵A中的马鞍点
{
int i,j,min,flag;
for(i=0;i<m;i++)
{
for(min=A[i][0],j=0;j<n;j++)
if(A[i][j]<min) min=A[i][j]; //求一行中的最小值
for(j=0;j<n;j++)
if(A[i][j]==min) //判断最小值是否是马鞍点
{
for(flag=1,k=0;k<m;k++)
if(min<A[k][j]) flag=0;
if(flag)
printf("%d",A[i][j]);
}
}
}
void Merge(LinkList &A,LinkList &B,LinkList &C) //假设是递增序列
{
LinkList p,q,r;
p=A->next;
q=B->next;
r=C=A;
while(p&&q)
{
if(p->data<q->data)
{
r->next=p;
r=r->next;
p=p->next;
}
else
{
r->next=q;
r=r->next;
q=q->next;
}
}
r->next=(p!=NULL?p:q);
free(B);
}
‘伍’ 对于无向图的邻接矩阵存储结构,判断是否有回路
邻接矩阵的话,从一个点出发(假设a)看它与哪个节点(假设b)有路径,那么再接着看b与谁有路,挨个试完以后,如果又回到了a,那就构成了一条回路。
‘陆’ 怎么写一个算法确定一个有N个顶点的有向图是否包含回路,此算法时间的代价应该是O(n),要用C来写
对于这个题目我们可以用DFS来做,每当访问当前节点的邻接表时,如果存在某个邻接的元素已被标记为访问状态,那么这个图就是存在回路的。
‘柒’ 邻接表 判断有向图是否有环 python
邻接表还是逆邻接表看如果是逆邻接表,每个顶点出发邻接表的链表中的结点个数就是入度
如果是邻接表过程如下:
有一个辅助数组,大小就是顶点数量,所有元素初值都为0
从头到尾遍历每个顶点出发的邻接表的结点,只要当前结点的数据是几(也就是第几个结点被有向弧进入了),这个下标的辅助数组元素加1,等所有的邻接表的小链表遍历完了,这个辅助数组中各个下标的数字就是该顶点的入度
‘捌’ 如何判断有向图中是否存在环
解法一:深度遍历
假设图以邻接矩阵表示,一条深度遍历路线中如果有结点被第二次访问到,那么有环。我们用一个变量来标记某结点的访问状态(未访问,访问过,其后结点都被访问过),然后判断每一个结点的深度遍历路线即可。
因为采用邻接矩阵存储,一般至少需要将矩阵中元素的一半给过一下,由于矩阵元素个数为n^2, 因此时间复杂度就是O(n^2)。如果采用邻接表存储,则只存储了边结点(e条边,无向图是2e条边),加上表头结点为n(也就是顶点个数),因此时间复杂度为O(n+e)。
解法二:拓扑排序
方法是重复寻找一个入度为0的顶点,将该顶点从图中删除(即放进一个队列里存着,这个队列的顺序就是最后的拓扑排序,具体见程序),并将该结点及其所有的出边从图中删除(即该结点指向的结点的入度减1),最终若图中全为入度为1的点,则这些点至少组成一个回路。
采用邻接矩阵存储时,遍历二维数组,求各顶点入度的时间复杂度是O(n^2)。 遍历所有结点,找出入度为0的结点的时间复杂度是O(n)。对于n个入度为0的结点,删除他们的出边的复杂度为O(n^2)。 所以总的复杂度为O(n^2)。
对于邻接表,遍历所有边,求各顶点入度的时间复杂度是O(e),即边的个数。遍历所有结点,找出入度为0的结点的时间复杂度是O(n),即顶点的个数。遍历所有边,删除入度为0的结点的出边的复杂度为O(e),即边的个数。所以总的时间复杂度是O(n+e)。
‘玖’ 怎么用深度遍历判断有向图是否有环
图用邻接矩阵表示。用回溯法实现非递归深度优先遍历图,如果是无向图,则遍历时只看上三角,如果是有向图,则不加限制。遍历时,如果遇到了之前访问过的结点,则图中存在环。
‘拾’ 此程序为判断以邻接表方式存储的有向图中是否存在有vi到Vj的路径,请大虾们帮我改正一下,最好写出正确程序
10分- -直接懒得看,,