问答题 试设计一个算法,判断一个有向无环图G中是否存在这样的顶点,该顶点到其他任意顶点都有一条有向路径。有向图G以邻接表的形式存储。
问答题 给出算法的基本设计思想以及结点和邻接表的定义。
【正确答案】基本设计思想:若存在这样的顶点,该顶点到其他任一结点都有一条有向路,又因为该有向图是无环路的,那么该顶点到这些结点之间的路构成一棵树,此树上的结点数应该等于该图的结点数。若不等于(小于),则不存在这样的结点。因此,从任意结点开始,遍历此图(深度优先或者是广度优先均可),若visited的结点数等于图的结点数,则存在,否则不存在。结点和邻接表定义如下:
Struct node
{
int adjvex;
node *next;
};//结点的定义
struct g
{
vertexttype data;
node *firstarc;
}typedef g ADJLIST;//邻接表的定义
【答案解析】
问答题 根据设计思想,采用C、C++语言描述算法,关键之处给出注释。
【正确答案】算法实现如下: 方法一:广度优先遍历(使用队列) int rbfs(ADJLIST g,int vi) { int i,count,yes; yes=0; count=1; queue Q; for(int i=0;i<n;i++)visited[i]=0;//初始化访问标记数组 enqueue(vi,Q); visited[vi]=1;//初始化 while(!empty(Q)&&!yes) { int w=Q.front; p=g[w].firstarc; while(p!=NULL&&!yes) { W=P->adjdata; if(visited[w]=0) { visited[w]=1; count++; enqueue(W,Q); } else p=p->next; } } if(count==n)//n为该有向图中结点的总数 yes=1; return yes; } 方法二:深度优先遍历(使用栈) int rdfs(ADJLIST g,int vi) { int i,count,yes; yes=0; count=1; stack s; for(int i=0;i<n;i++)visited[i]=0;//初始化访问标记数组 push(vi,s); visited[vi]=1;//初始化 while(!empty(s)&&yes==0) { int w=top(s); p=g[w].firstarc; while(p!=NULL&&visited[p->adjdata]) { p=p->next; if(p==NULL)pop(s); elSe { w=p->adjdata; visited[w]=1; count++; push(w,s); } } } if(count==n)//n为该有向图中的结点数 yes=1; return yes; {
【答案解析】
问答题 说明你所设计算法的时间复杂度。
【正确答案】时间复杂度分析:无论是采用深度优先遍历还是广度优先遍历,可知每个结点均访问了一次,因此时间复杂度为O(n)。
【答案解析】