数据结构(c语言版)题集答案——第七章_图

数据结构(c语言版)题集答案——第七章_图
数据结构(c语言版)题集答案——第七章_图

第七章图

7.14

Status Build_AdjList(ALGraph &G)//输入有向图的顶点数,边数,顶点信息和边的信息建立邻接表

{

InitALGraph(G);

scanf("%d",&v);

if(v<0) return ERROR; //顶点数不能为负

G.vexnum=v;

scanf("%d",&a);

if(a<0) return ERROR; //边数不能为负

G.arcnum=a;

for(m=0;mG.vertices[m].data=getchar(); //输入各顶点的符号

for(m=1;m<=a;m++)

{

t=getchar();h=getchar(); //t为弧尾,h为弧头

if((i=LocateV ex(G,t))<0) return ERROR;

if((j=LocateV ex(G,h))<0) return ERROR; //顶点未找到

p=(ArcNode*)malloc(sizeof(ArcNode));

if(!G.vertices.[i].firstarc) G.vertices[i].firstarc=p;

else

{

for(q=G.vertices[i].firstarc;q->nextarc;q=q->nextarc);

q->nextarc=p;

}

p->adjvex=j;p->nextarc=NULL;

}//while

return OK;

}//Build_AdjList

7.15

//本题中的图G均为有向无权图,其余情况容易由此写出

Status Insert_V ex(MGraph &G, char v)//在邻接矩阵表示的图G上插入顶点v

{

if(G.vexnum+1)>MAX_VERTEX_NUM return INFEASIBLE;

G.vexs[++G.vexnum]=v;

return OK;

}//Insert_V ex

Status Insert_Arc(MGraph &G,char v,char w)//在邻接矩阵表示的图G上插入边(v,w)

{

if((i=LocateV ex(G,v))<0) return ERROR;

if((j=LocateV ex(G,w))<0) return ERROR;

if(i==j) return ERROR;

if(!G.arcs[i][j].adj)

{

G.arcs[i][j].adj=1;

G.arcnum++;

}

return OK;

}//Insert_Arc

Status Delete_V ex(MGraph &G,char v)//在邻接矩阵表示的图G上删除顶点v

{

n=G.vexnum;

if((m=LocateV ex(G,v))<0) return ERROR;

G.vexs[m]<->G.vexs[n]; //将待删除顶点交换到最后一个顶点

for(i=0;i{

G.arcs[i][m]=G.arcs[i][n];

G.arcs[m][i]=G.arcs[n][i]; //将边的关系随之交换

}

G.arcs[m][m].adj=0;

G.vexnum--;

return OK;

}//Delete_V ex

分析:如果不把待删除顶点交换到最后一个顶点的话,算法将会比较复杂,而伴随着大量元素的移动,时间复杂度也会大大增加.

Status Delete_Arc(MGraph &G,char v,char w)//在邻接矩阵表示的图G上删除边(v,w)

{

if((i=LocateV ex(G,v))<0) return ERROR;

if((j=LocateV ex(G,w))<0) return ERROR;

if(G.arcs[i][j].adj)

{

G.arcs[i][j].adj=0;

G.arcnum--;

}

return OK;

}//Delete_Arc

7.16

//为节省篇幅,本题只给出Insert_Arc算法.其余算法请自行写出.

Status Insert_Arc(ALGraph &G,char v,char w)//在邻接表表示的图G上插入边(v,w)

{

if((i=LocateV ex(G,v))<0) return ERROR;

if((j=LocateV ex(G,w))<0) return ERROR;

p=(ArcNode*)malloc(sizeof(ArcNode));

p->adjvex=j;p->nextarc=NULL;

if(!G.vertices[i].firstarc) G.vertices[i].firstarc=p;

else

{

for(q=G.vertices[i].firstarc;q->q->nextarc;q=q->nextarc)

if(q->adjvex==j) return ERROR; //边已经存在

q->nextarc=p;

}

G.arcnum++;

return OK;

}//Insert_Arc

7.17

//为节省篇幅,本题只给出较为复杂的Delete_V ex算法.其余算法请自行写出. Status Delete_V ex(OLGraph &G,char v)//在十字链表表示的图G上删除顶点v {

if((m=LocateV ex(G,v))<0) return ERROR;

n=G.vexnum;

for(i=0;i{

if(G.xlist[i].firstin->tailvex==m) //如果待删除的边是头链上的第一个结点{

q=G.xlist[i].firstin;

G.xlist[i].firstin=q->hlink;

free(q);G.arcnum--;

}

else //否则

{

for(p=G.xlist[i].firstin;p&&p->hlink->tailvex!=m;p=p->hlink);

if(p)

{

q=p->hlink;

p->hlink=q->hlink;

free(q);G.arcnum--;

}

}//else

}//for

for(i=0;i{

if(G.xlist[i].firstout->headvex==m) //如果待删除的边是尾链上的第一个结点{

q=G.xlist[i].firstout;

G.xlist[i].firstout=q->tlink;

free(q);G.arcnum--;

}

else //否则

{

for(p=G.xlist[i].firstout;p&&p->tlink->headvex!=m;p=p->tlink);

if(p)

{

q=p->tlink;

p->tlink=q->tlink;

free(q);G.arcnum--;

}

}//else

}//for

for(i=m;i{

G.xlist[i]=G.xlist[i+1]; //修改表头向量

for(p=G.xlist[i].firstin;p;p=p->hlink)

p->headvex--;

for(p=G.xlist[i].firstout;p;p=p->tlink)

p->tailvex--; //修改各链中的顶点序号

}

G.vexnum--;

return OK;

}//Delete_V ex

7.18

//为节省篇幅,本题只给出Delete_Arc算法.其余算法请自行写出.

Status Delete_Arc(AMLGraph &G,char v,char w)////在邻接多重表表示的图G上删除边(v,w) {

if((i=LocateV ex(G,v))<0) return ERROR;

if((j=LocateV ex(G,w))<0) return ERROR;

if(G.adjmulist[i].firstedge->jvex==j)

G.adjmulist[i].firstedge=G.adjmulist[i].firstedge->ilink;

else

{

for(p=G.adjmulist[i].firstedge;p&&p->ilink->jvex!=j;p=p->ilink);

if (!p) return ERROR; //未找到

p->ilink=p->ilink->ilink;

} //在i链表中删除该边

if(G.adjmulist[j].firstedge->ivex==i)

G.adjmulist[j].firstedge=G.adjmulist[j].firstedge->jlink;

else

{

for(p=G.adjmulist[j].firstedge;p&&p->jlink->ivex!=i;p=p->jlink);

if (!p) return ERROR; //未找到

q=p->jlink;

p->jlink=q->jlink;

free(q);

} //在i链表中删除该边

G.arcnum--;

return OK;

}//Delete_Arc

7.19

Status Build_AdjMulist(AMLGraph &G)//输入有向图的顶点数,边数,顶点信息和边的信息建立邻接多重表

{

InitAMLGraph(G);

scanf("%d",&v);

if(v<0) return ERROR; //顶点数不能为负

G.vexnum=v;

scanf(%d",&a);

if(a<0) return ERROR; //边数不能为负

G.arcnum=a;

for(m=0;mG.adjmulist[m].data=getchar(); //输入各顶点的符号

for(m=1;m<=a;m++)

{

t=getchar();h=getchar(); //t为弧尾,h为弧头

if((i=LocateV ex(G,t))<0) return ERROR;

if((j=LocateV ex(G,h))<0) return ERROR; //顶点未找到

p=(EBox*)malloc(sizeof(EBox));

p->ivex=i;p->jvex=j;

p->ilink=NULL;p->jlink=NULL; //边结点赋初值

if(!G.adjmulist[i].firstedge) G.adjmulist[i].firstedge=p;

else

{

q=G.adjmulist[i].firstedge;

while(q)

{

r=q;

if(q->ivex==i) q=q->ilink;

else q=q->jlink;

}

if(r->ivex==i) r->ilink=p;//注意i值既可能出现在边结点的ivex域中, else r->jlink=p; //又可能出现在边结点的jvex域中

}//else //插入i链表尾部

if(!G.adjmulist[j].firstedge) G.adjmulist[j].firstedge=p;

else

{

q=G.adjmulist[i].firstedge;

while(q)

{

r=q;

if(q->jvex==j) q=q->jlink;

else q=q->ilnk;

}

if(r->jvex==j) r->jlink=p;

else r->ilink=p;

}//else //插入j链表尾部

}//for

return OK;

}//Build_AdjList

7.20

int Pass_MGraph(MGraph G)//判断一个邻接矩阵存储的有向图是不是可传递的,是则返回1,否则返回0

{

for(x=0;xfor(y=0;yif(G.arcs[x][y])

{

for(z=0;zif(z!=x&&G.arcs[y][z]&&!G.arcs[x][z]) return 0;//图不可传递的条件

}//if

return 1;

}//Pass_MGraph

分析:本算法的时间复杂度大概是O(n^2*d).

7.21

int Pass_ALGraph(ALGraph G)//判断一个邻接表存储的有向图是不是可传递的,是则返回1,否则返回0

{

for(x=0;xfor(p=G.vertices[x].firstarc;p;p=p->nextarc)

{

y=p->adjvex;

for(q=G.vertices[y].firstarc;q;q=q->nextarc)

{

z=q->adjvex;

if(z!=x&&!is_adj(G,x,z)) return 0;

}//for

}//for

}//Pass_ALGraph

int is_adj(ALGraph G,int m,int n)//判断有向图G中是否存在边(m,n),是则返回1,否则返回0 {

for(p=G.vertices[m].firstarc;p;p=p->nextarc)

if(p->adjvex==n) return 1;

return 0;

}//is_adj

7.22

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

7.23

int exist_path_BFS(ALGraph 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[u]=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

7.24

void STraverse_Nonrecursive(Graph G)//非递归遍历强连通图G

{

int visited[MAXSIZE];

InitStack(S);

Push(S,GetV ex(S,1)); //将第一个顶点入栈

visit(1);

visited =1;

while(!StackEmpty(S))

{

while(Gettop(S,i)&&i)

{

j=FirstAdjV ex(G,i);

if(j&&!visited[j])

{

visit(j);

visited[j]=1;

Push(S,j); //向左走到尽头

}

}//while

if(!StackEmpty(S))

{

Pop(S,j);

Gettop(S,i);

k=NextAdjV ex(G,i,j); //向右走一步

if(k&&!visited[k])

{

visit(k);

visited[k]=1;

Push(S,k);

}

}//if

}//while

}//Straverse_Nonrecursive

分析:本算法的基本思想与二叉树的先序遍历非递归算法相同,请参考6.37.由于是强连通图,所以从第一个结点出发一定能够访问到所有结点.

7.25

见书后解答.

7.26

Status TopoNo(ALGraph G)//按照题目要求顺序重排有向图中的顶点

{

int new[MAXSIZE],indegree[MAXSIZE]; //储存结点的新序号

n=G.vexnum;

FindInDegree(G,indegree);

InitStack(S);

for(i=1;iif(!indegree[i]) Push(S,i); //零入度结点入栈

count=0;

while(!StackEmpty(S))

{

Pop(S,i);

new[i]=n--; //记录结点的拓扑逆序序号

count++;

for(p=G.vertices[i].firstarc;p;p=p->nextarc)

{

k=p->adjvex;

if(!(--indegree[k])) Push(S,k);

}//for

}//while

if(countfor(i=1;i<=n;i++) printf("Old No:%d New No:%d\n",i,new[i])

return OK;

}//TopoNo

分析:只要按拓扑逆序对顶点编号,就可以使邻接矩阵成为下三角矩阵.

7.27

int visited[MAXSIZE];

int exist_path_len(ALGraph G,int i,int j,int k)//判断邻接表方式存储的有向图G的顶点i到j是否存在长度为k的简单路径

{

if(i==j&&k==0) return 1; //找到了一条路径,且长度符合要求

else if(k>0)

{

visited[i]=1;

for(p=G.vertices[i].firstarc;p;p=p->nextarc)

{

l=p->adjvex;

if(!visited[l])

if(exist_path_len(G,l,j,k-1)) return 1; //剩余路径长度减一

}//for

visited[i]=0; //本题允许曾经被访问过的结点出现在另一条路径中

}//else

return 0; //没找到

}//exist_path_len

7.28

int path[MAXSIZE],visited[MAXSIZE]; //暂存遍历过程中的路径

int Find_All_Path(ALGraph G,int u,int v,int k)//求有向图G中顶点u到v之间的所有简单路径,k 表示当前路径长度

{

path[k]=u; //加入当前路径中

visited[u]=1;

if(u==v) //找到了一条简单路径

{

printf("Found one path!\n");

for(i=0;path[i];i++) printf("%d",path[i]); //打印输出

}

else

for(p=G.vertices[u].firstarc;p;p=p->nextarc)

{

l=p->adjvex;

if(!visited[l]) Find_All_Path(G,l,v,k+1); //继续寻找

}

visited[u]=0;

path[k]=0; //回溯

}//Find_All_Path

main()

{

...

Find_All_Path(G,u,v,0); //在主函数中初次调用,k值应为0

...

}//main

7.29

int GetPathNum_Len(ALGraph G,int i,int j,int len)//求邻接表方式存储的有向图G的顶点i到j 之间长度为len的简单路径条数

{

if(i==j&&len==0) return 1; //找到了一条路径,且长度符合要求

else if(len>0)

{

sum=0; //sum表示通过本结点的路径数

visited[i]=1;

for(p=G.vertices[i].firstarc;p;p=p->nextarc)

{

l=p->adjvex;

if(!visited[l])

sum+=GetPathNum_Len(G,l,j,len-1)//剩余路径长度减一

}//for

visited[i]=0; //本题允许曾经被访问过的结点出现在另一条路径中

}//else

return sum;

}//GetPathNum_Len

7.30

int visited[MAXSIZE];

int path[MAXSIZE]; //暂存当前路径

int cycles[MAXSIZE][MAXSIZE]; //储存发现的回路所包含的结点

int thiscycle[MAXSIZE]; //储存当前发现的一个回路

int cycount=0; //已发现的回路个数

void GetAllCycle(ALGraph G)//求有向图中所有的简单回路

{

for(v=0;vfor(v=0;vif(!visited[v]) DFS(G,v,0); //深度优先遍历

}//DFSTraverse

void DFS(ALGraph G,int v,int k)//k表示当前结点在路径上的序号

{

visited[v]=1;

path[k]=v; //记录当前路径

for(p=G.vertices[v].firstarc;p;p=p->nextarc)

{

w=p->adjvex;

if(!visited[w]) DFS(G,w,k+1);

else //发现了一条回路

{

for(i=0;path[i]!=w;i++); //找到回路的起点

for(j=0;path[i+j];i++) thiscycle[j]=path[i+j];//把回路复制下来

if(!exist_cycle()) cycles[cycount++]=thiscycle;//如果该回路尚未被记录过,就添加到记录中

for(i=0;i}//else

}//for

path[k]=0;

visited[k]=0; //注意只有当前路径上的结点visited为真.因此一旦遍历中发现当前结点visited 为真,即表示发现了一条回路

}//DFS

int exist_cycle()//判断thiscycle数组中记录的回路在cycles的记录中是否已经存在

{

int temp[MAXSIZE];

for(i=0;i{ //也就是,所有结点和它们的顺序都相同

j=0;c=thiscycle�; //例如,142857和857142是相同的回路

for(k=0;cycles[i][k]!=c&&cycles[i][k]!=0;k++);//在cycles的一个行向量中寻找等于thiscycle 第一个结点的元素

if(cycles[i][k]) //有与之相同的一个元素

{

for(m=0;cycles[i][k+m];m++)

temp[m]=cycles[i][k+m];

for(n=0;ntemp[m]=cycles[i][n]; //调整cycles中的当前记录的循环相位并放入temp数组中

if(!StrCompare(temp,thiscycle)) //与thiscycle比较

return 1; //完全相等

for(m=0;m}

}//for

return 0; //所有现存回路都不与thiscycle完全相等

}//exist_cycle

分析:这个算法的思想是,在遍历中暂存当前路径,当遇到一个结点已经在路径之中时就表明存在一条回路;扫描路径向量path可以获得这条回路上的所有结点.把结点序列(例如,142857)存入thiscycle中;由于这种算法中,一条回路会被发现好几次,所以必须先判断该回路是否已经在cycles中被记录过,如果没有才能存入cycles的一个行向量中.把cycles的每一个行向量取出来与之比较.由于一条回路可能有多种存储顺序,比如142857等同于285714和571428,所以还要调整行向量的次序,并存入temp数组,例如,thiscycle为142857第一个结点为1,cycles 的当前向量为857142,则找到后者中的1,把1后部分提到1前部分前面,最终在temp中得到142857,与thiscycle比较,发现相同,因此142857和857142是同一条回路,不予存储.这个算法太复杂,很难保证细节的准确性,大家理解思路便可.希望有人给出更加简捷的算法.

7.31

int visited[MAXSIZE];

int finished[MAXSIZE];

int count; //count在第一次深度优先遍历中用于指示finished数组的填充位置

void Get_SGraph(OLGraph G)//求十字链表结构储存的有向图G的强连通分量

{

count=0;

for(v=0;vfor(v=0;vif(!visited[v]) DFS1(G,v);

for(v=0;vfor(i=G.vexnum-1;i>=0;i--) //第二次逆向的深度优先遍历

{

v=finished(i);

if(!visited[v])

{

printf("\n"); //不同的强连通分量在不同的行输出

DFS2(G,v);

}

}//for

}//Get_SGraph

void DFS1(OLGraph G,int v)//第一次深度优先遍历的算法

{

visited[v]=1;

for(p=G.xlist[v].firstout;p;p=p->tlink)

{

w=p->headvex;

if(!visited[w]) DFS1(G,w);

}//for

finished[++count]=v; //在第一次遍历中建立finished数组

}//DFS1

void DFS2(OLGraph G,int v)//第二次逆向的深度优先遍历的算法

{

visited[v]=1;

printf("%d",v); //在第二次遍历中输出结点序号

for(p=G.xlist[v].firstin;p;p=p->hlink)

{

w=p->tailvex;

if(!visited[w]) DFS2(G,w);

}//for

}//DFS2

分析:求有向图的强连通分量的算法的时间复杂度和深度优先遍历相同,也为O(n+e).

7.32

void Forest_Prim(ALGraph G,int k,CSTree &T)//从顶点k出发,构造邻接表结构的有向图G的最小生成森林T,用孩子兄弟链表存储

{

for(j=0;jif(j!=k)

{

closedge[j]={k,Max_int};

for(p=G.vertices[j].firstarc;p;p=p->nextarc)

if(p->adjvex==k) closedge[j].lowcost=p->cost;

}//if

closedge[k].lowcost=0;

for(i=1;i{

k=minimum(closedge);

if(closedge[k].lowcost{

Addto_Forest(T,closedge[k].adjvex,k); //把这条边加入生成森林中

closedge[k].lowcost=0;

for(p=G.vertices[k].firstarc;p;p=p->nextarc)

if(p->costadjvex].lowcost)

closedge[p->adjvex]={k,p->cost};

}//if

else Forest_Prim(G,k); //对另外一个连通分量执行算法

}//for

}//Forest_Prim

void Addto_Forest(CSTree &T,int i,int j)//把边(i,j)添加到孩子兄弟链表表示的树T中

{

p=Locate(T,i); //找到结点i对应的指针p,过程略

q=(CSTNode*)malloc(sizeof(CSTNode));

q->data=j;

if(!p) //起始顶点不属于森林中已有的任何一棵树

{

p=(CSTNode*)malloc(sizeof(CSTNode));

p->data=i;

for(r=T;r->nextsib;r=r->nextsib);

r->nextsib=p;

p->firstchild=q;

} //作为新树插入到最右侧

else if(!p->firstchild) //双亲还没有孩子

p->firstchild=q; //作为双亲的第一个孩子

else //双亲已经有了孩子

{

for(r=p->firstchild;r->nextsib;r=r->nextsib);

r->nextsib=q; //作为双亲最后一个孩子的兄弟

}

}//Addto_Forest

main()

{

...

T=(CSTNode*)malloc(sizeof(CSTNode)); //建立树根

T->data=1;

Forest_Prim(G,1,T);

...

}//main

分析:这个算法是在Prim算法的基础上添加了非连通图支持和孩子兄弟链表构建模块而得到的,其时间复杂度为O(n^2).

7.33

typedef struct {

int vex; //结点序号

int ecno; //结点所属的连通分量号

} V exInfo;

V exInfo vexs[MAXSIZE]; //记录结点所属连通分量号的数组

void Init_V exInfo(V exInfo &vexs[ ],int vexnum)//初始化

{

for(i=0;ivexs[i]={i,i}; //初始状态:每一个结点都属于不同的连通分量

}//Init_V exInfo

int is_ec(V exInfo vexs[ ],int i,int j)//判断顶点i和顶点j是否属于同一个连通分量

{

if(vexs[i].ecno==vexs[j].ecno) return 1;

else return 0;

}//is_ec

void merge_ec(V exInfo &vexs[ ],int ec1,int ec2)//合并连通分量ec1和ec2

{

for(i=0;vexs[i].vex;i++)

if(vexs[i].ecno==ec2) vexs[i].ecno==ec1;

}//merge_ec

void MinSpanTree_Kruscal(Graph G,EdgeSetType &EdgeSet,CSTree &T)//求图的最小生成树的克鲁斯卡尔算法

{

Init_V exInfo(vexs,G.vexnum);

ecnum=G.vexnum; //连通分量个数

while(ecnum>1)

{

GetMinEdge(EdgeSet,u,v); //选出最短边

if(!is_ec(vexs,u,v)) //u和v属于不同连通分量

{

Addto_CSTree(T,u,v); //加入到生成树中

merge_ec(vexs,vexs[u].ecno,vexs[v].ecno); //合并连通分量

ecnum--;

}

DelMinEdge(EdgeSet,u,v); //从边集中删除

}//while

}//MinSpanTree_Kruscal

void Addto_CSTree(CSTree &T,int i,int j)//把边(i,j)添加到孩子兄弟链表表示的树T中

{

p=Locate(T,i); //找到结点i对应的指针p,过程略

q=(CSTNode*)malloc(sizeof(CSTNode));

q->data=j;

if(!p->firstchild) //双亲还没有孩子

p->firstchild=q; //作为双亲的第一个孩子

else //双亲已经有了孩子

{

for(r=p->firstchild;r->nextsib;r=r->nextsib);

r->nextsib=q; //作为双亲最后一个孩子的兄弟

}

}//Addto_CSTree

分析:本算法使用一维结构体变量数组来表示等价类,每个连通分量所包含的所有结点属于一个等价类.在这个结构上实现了初始化,判断元素是否等价(两个结点是否属于同一个连通分

量),合并等价类(连通分量)的操作.

7.34

Status TopoSeq(ALGraph G,int new[ ])//按照题目要求给有向无环图的结点重新编号,并存入数组new中

{

int indegree[MAXSIZE]; //本算法就是拓扑排序

FindIndegree(G,indegree);

Initstack(S);

for(i=0;iif(!indegree[i]) Push(S,i);

count=0;

while(!stackempty(S))

{

Pop(S,i);new[i]=++count; //把拓扑顺序存入数组的对应分量中

for(p=G.vertices[i].firstarc;p;p=p->nextarc)

{

k=p->adjvex;

if(!(--indegree[k])) Push(S,k);

}

}//while

if(countreturn OK;

}//TopoSeq

7.35

int visited[MAXSIZE];

void Get_Root(ALGraph G)//求有向无环图的根,如果有的话

{

for(v=0;v{

for(w=0;wDFS(G,v); //从顶点v出发进行深度优先遍历

for(flag=1,w=0;wif(!visited[w]) flag=0; //如果v是根,则深度优先遍历可以访问到所有结点

if(flag) printf("Found a root vertex:%d\n",v);

}//for

}//Get_Root,这个算法要求图中不能有环,否则会发生误判

void DFS(ALGraph G,int v)

{

visited[v]=1;

for(p=G.vertices[v].firstarc;p;p=p->nextarc)

{

w=p->adjvex;

if(!visited[w]) DFS(G,w);

}

}//DFS

7.36

void Fill_MPL(ALGraph &G)//为有向无环图G添加MPL域

{

FindIndegree(G,indegree);

for(i=0;iif(!indegree[i]) Get_MPL(G,i);//从每一个零入度顶点出发构建MPL域}//Fill_MPL

int Get_MPL(ALGraph &G,int i)//从一个顶点出发构建MPL域并返回其MPL值{

if(!G.vertices[i].firstarc)

{

G.vertices[i].MPL=0;

return 0; //零出度顶点

}

else

{

max=0;

for(p=G.vertices[i].firstarc;p;p=p->nextarc)

{

j=p->adjvex;

if(G.vertices[j].MPL==0) k=Get_MPL(G,j);

if(k>max) max=k; //求其直接后继顶点MPL的最大者

}

G.vertices[i]=max+1;//再加一,就是当前顶点的MPL

return max+1;

}//else

}//Get_MPL

7.37

int maxlen,path[MAXSIZE]; //数组path用于存储当前路径

int mlp[MAXSIZE]; //数组mlp用于存储已发现的最长路径

void Get_Longest_Path(ALGraph G)//求一个有向无环图中最长的路径

{

maxlen=0;

FindIndegree(G,indegree);

for(i=0;i{

for(j=0;jif(!indegree[i]) DFS(G,i,0);//从每一个零入度结点开始深度优先遍历

}

printf("Longest Path:");

for(i=0;mlp[i];i++) printf("%d",mlp[i]); //输出最长路径

}//Get_Longest_Path

void DFS(ALGraph G,int i,int len)

{

visited[i]=1;

path[len]=i;

if(len>maxlen&&!G.vertices[i].firstarc) //新的最长路径

{

for(j=0;j<=len;j++) mlp[j]=path[j]; //保存下来

maxlen=len;

}

else

{

for(p=G.vertices[i].firstarc;p;p=p->nextarc)

{

j=p->adjvex;

if(!visited[j]) DFS(G,j,len+1);

}

}//else

path[i]=0;

visited[i]=0;

}//DFS

7.38

void NiBoLan_DAG(ALGraph G)//输出有向无环图形式表示的表达式的逆波兰式

{

FindIndegree(G,indegree);

for(i=0;iif(!indegree[i]) r=i; //找到有向无环图的根

PrintNiBoLan_DAG(G,i);

}//NiBoLan_DAG

void PrintNiBoLan_DAG(ALGraph G,int i)//打印输出以顶点i为根的表达式的逆波兰式{

c=G.vertices[i].data;

if(!G.vertices[i].firstarc) //c是原子

printf("%c",c);

else //子表达式

{

p=G.vertices[i].firstarc;

PrintNiBoLan_DAG(G,p->adjvex);

PrintNiBoLan_DAG(G,p->nexarc->adjvex);

printf("%c",c);

}

}//PrintNiBoLan_DAG

7.39

void PrintNiBoLan_Bitree(Bitree T)//在二叉链表存储结构上重做上一题

{

if(T->lchild) PrintNiBoLan_Bitree(T->lchild);

if(T->rchild) PrintNiBoLan_Bitree(T->rchild);

printf("%c",T->data);

}//PrintNiBoLan_Bitree

7.40

int Evaluate_DAG(ALGraph G)//给有向无环图表示的表达式求值

{

FindIndegree(G,indegree);

for(i=0;iif(!indegree[i]) r=i; //找到有向无环图的根

return Evaluate_imp(G,i);

}//NiBoLan_DAG

int Evaluate_imp(ALGraph G,int i)//求子表达式的值

{

if(G.vertices[i].tag=NUM) return G.vertices[i].value;

else

{

p=G.vertices[i].firstarc;

v1=Evaluate_imp(G,p->adjvex);

v2=Evaluate_imp(G,p->nextarc->adjvex);

return calculate(v1,G.vertices[i].optr,v2);

}

}//Evaluate_imp

分析:本题中,邻接表的vertices向量的元素类型修改如下:

struct {

enum tag{NUM,OPTR};

union {

int value;

char optr;

};

ArcNode * firstarc;

} Elemtype;

7.41

void Critical_Path(ALGraph G)//利用深度优先遍历求网的关键路径{

FindIndegree(G,indegree);

for(i=0;iif(!indegree[i]) DFS1(G,i); //第一次深度优先遍历:建立ve for(i=0;iif(!indegree[i]) DFS2(G,i); //第二次深度优先遍历:建立vl for(i=0;i<=G.vexnum;i++)

if(vl[i]==ve[i]) printf("%d",i); //打印输出关键路径

}//Critical_Path

void DFS1(ALGraph G,int i)

{

if(!indegree[i]) ve[i]=0;

for(p=G.vertices[i].firstarc;p;p=p->nextarc)

{

dut=*p->info;

if(ve[i]+dut>ve[p->adjvex])

ve[p->adjvex]=ve[i]+dut;

DFS1(G,p->adjvex);

}

}//DFS1

void DFS2(ALGraph G,int i)

{

if(!G.vertices[i].firstarc) vl[i]=ve[i];

else

{

for(p=G.vertices[i].firstarc;p;p=p->nextarc)

{

DFS2(G,p->adjvex);

dut=*p->info;

if(vl[p->adjvex]-dutvl[i]=vl[p->adjvex]-dut;

}

}//else

}//DFS2

7.42

void ALGraph_DIJ(ALGraph G,int v0,Pathmatrix &P,ShortestPathTable &D)//在邻接表存储结构上实现迪杰斯特拉算法

{

for(v=0;vD[v]=INFINITY;

for(p=G.vertices[v0].firstarc;p;p=p->nextarc)

D[p->adjvex]=*p->info; //给D数组赋初值

for(v=0;v{

final[v]=0;

for(w=0;wif(D[v]{

P[v][v0]=1;

P[v][v]=1;

}

}//for

D[v0]=0;final[v0]=1; //初始化

for(i=1;i{

min=INFINITY;

for(w=0;wif(!final[w])

if(D[w]{

v=w;

min=D[w];

}

final[v]=1;

for(p=G.vertices[v].firstarc;p;p=p->nextarc)

{

w=p->adjvex;

if(!final[w]&&(min+(*p->info){

D[w]=min+edgelen(G,v,w);

P[w]=P[v];

P[w][w]=1; //构造最短路径

}

}//for

}//for

}//ALGraph_DIJ

分析:本算法对迪杰斯特拉算法中直接取任意边长度的语句作了修改.由于在原算法中,每次循环都是对尾相同的边进行处理,所以可以用遍历邻接表中的一条链来代替.

数据结构C语言版期末考试试题(有答案)

“数据结构”期末考试试题 一、单选题(每小题2分,共12分) 1.在一个单链表HL中,若要向表头插入一个由指针p指向的结点,则执行( )。 A. HL=ps p一>next=HL B. p一>next=HL;HL=p3 C. p一>next=Hl;p=HL; D. p一>next=HL一>next;HL一>next=p; 2.n个顶点的强连通图中至少含有( )。 A.n—l条有向边 B.n条有向边 C.n(n—1)/2条有向边 D.n(n一1)条有向边 3.从一棵二叉搜索树中查找一个元素时,其时间复杂度大致为( )。 A.O(1) B.O(n) C.O(1Ogzn) D.O(n2) 4.由权值分别为3,8,6,2,5的叶子结点生成一棵哈夫曼树,它的带权路径长度为( )。 A.24 B.48 C. 72 D. 53 5.当一个作为实际传递的对象占用的存储空间较大并可能需要修改时,应最好把它说明为( )参数,以节省参数值的传输时间和存储参数的空间。 A.整形 B.引用型 C.指针型 D.常值引用型· 6.向一个长度为n的顺序表中插人一个新元素的平均时间复杂度为( )。 A.O(n) B.O(1) C.O(n2) D.O(10g2n) 二、填空题(每空1分,共28分) 1.数据的存储结构被分为——、——、——和——四种。 2.在广义表的存储结构中,单元素结点与表元素结点有一个域对应不同,各自分别为——域和——域。 3.——中缀表达式 3十x*(2.4/5—6)所对应的后缀表达式为————。 4.在一棵高度为h的3叉树中,最多含有——结点。 5.假定一棵二叉树的结点数为18,则它的最小深度为——,最大深度为——· 6.在一棵二叉搜索树中,每个分支结点的左子树上所有结点的值一定——该结点的值,右子树上所有结点的值一定——该结点的值。 7.当向一个小根堆插入一个具有最小值的元素时,该元素需要逐层——调整,直到被调整到——位置为止。 8.表示图的三种存储结构为——、——和———。 9.对用邻接矩阵表示的具有n个顶点和e条边的图进行任一种遍历时,其时间复杂度为——,对用邻接表表示的图进行任一种遍历时,其时间复杂度为——。 10.从有序表(12,18,30,43,56,78,82,95)中依次二分查找43和56元素时,其查找长度分别为——和——· 11.假定对长度n=144的线性表进行索引顺序查找,并假定每个子表的长度均

《数据结构》习题汇编07 第七章 图 试题

第七章图试题 一、单项选择题 1.在无向图中定义顶点的度为与它相关联的()的数目。 A. 顶点 B. 边 C. 权 D. 权值 2.在无向图中定义顶点 v i与v j之间的路径为从v i到达v j的一个()。 A. 顶点序列 B. 边序列 C. 权值总和 D. 边的条数 3.图的简单路径是指()不重复的路径。 A. 权值 B. 顶点 C. 边 D. 边与顶点均 4.设无向图的顶点个数为n,则该图最多有()条边。 A. n-1 B. n(n-1)/2 C. n(n+1)/2 D. n(n-1) 5.n个顶点的连通图至少有()条边。 A. n-1 B. n C. n+1 D. 0 6.在一个无向图中,所有顶点的度数之和等于所有边数的 ( ) 倍。 A. 3 B. 2 C. 1 D. 1/2 7.若采用邻接矩阵法存储一个n个顶点的无向图,则该邻接矩阵是一个 ( )。 A. 上三角矩阵 B. 稀疏矩阵 C. 对角矩阵 D. 对称矩阵 8.图的深度优先搜索类似于树的()次序遍历。 A. 先根 B. 中根 C. 后根 D. 层次 9.图的广度优先搜索类似于树的()次序遍历。 A. 先根 B. 中根 C. 后根 D. 层次 10.在用Kruskal算法求解带权连通图的最小(代价)生成树时,通常采用一个()辅助结构, 判断一条边的两个端点是否在同一个连通分量上。 A. 位向量 B. 堆 C. 并查集 D. 生成树顶点集合 11.在用Kruskal算法求解带权连通图的最小(代价)生成树时,选择权值最小的边的原则是该边不能 在图中构成()。 A. 重边 B. 有向环 C. 回路 D. 权值重复的边 12.在用Dijkstra算法求解带权有向图的最短路径问题时,要求图中每条边所带的权值必须是 ()。 A. 非零 B. 非整 C. 非负 D. 非正 13.在一个连通图中进行深度优先搜索得到一棵深度优先生成树,树根结点是关节点的充要条件是它至少 有()子女。

数据结构c语言版期末考试复习试题

《数据结构与算法》复习题 一、选择题。 1在数据结构中,从逻辑上可以把数据结构分为 C 。 A ?动态结构和静态结构B.紧凑结构和非紧凑结构 C.线性结构和非线性结构 D.内部结构和外部结构 2?数据结构在计算机内存中的表示是指_A_。 A .数据的存储结构B.数据结构 C .数据的逻辑结构 D .数据元素之间的关系 3.在数据结构中,与所使用的计算机无关的是数据的A结构。 A .逻辑 B .存储C.逻辑和存储 D .物理 4.在存储数据时,通常不仅要存储各数据元素的值,而且还要存储_C A .数据的处理方法 B .数据元素的类型 C.数据元素之间的关系 D .数据的存储方法 5.在决定选取何种存储结构时,一般不考虑A A .各结点的值如何C.对数据有哪些运算 B .结点个数的多少 D .所用的编程语言实现这种结构是否方 6.以下说法正确的是D A .数据项是数据的基本单位 B .数据元素是数据的最小单位 C.数据结构是带结构的数据项的集合 D .一些表面上很不相同的数据可以有相同的逻辑结构 7.算法分析的目的是 C ,算法分析的两个主要方面是 A 。 (1) A .找出数据结构的合理性B.研究算法中的输入和输出的关系 C .分析算法的效率以求改进C.分析算法的易读性和文档性 (2) A .空间复杂度和时间复杂度B.正确性和简明性 &下面程序段的时间复杂度是0( n2) s =0; for( I =0; i

数据结构(c语言版)期末考试复习试题

《数据结构与算法》(c语言版)期末考复习题 一、选择题。 1.在数据结构中,从逻辑上可以把数据结构分为 C 。 A.动态结构和静态结构B.紧凑结构和非紧凑结构 C.线性结构和非线性结构D.内部结构和外部结构 2.数据结构在计算机内存中的表示是指 A 。 A.数据的存储结构B.数据结构C.数据的逻辑结构D.数据元素之间的关系 3.在数据结构中,与所使用的计算机无关的是数据的 A 结构。 A.逻辑B.存储C.逻辑和存储D.物理 4.在存储数据时,通常不仅要存储各数据元素的值,而且还要存储 C 。A.数据的处理方法B.数据元素的类型 C.数据元素之间的关系D.数据的存储方法 5.在决定选取何种存储结构时,一般不考虑 A 。 A.各结点的值如何B.结点个数的多少 C.对数据有哪些运算D.所用的编程语言实现这种结构是否方便。 6.以下说法正确的是 D 。 A.数据项是数据的基本单位

B.数据元素是数据的最小单位 C.数据结构是带结构的数据项的集合 D.一些表面上很不相同的数据可以有相同的逻辑结构 7.算法分析的目的是 C ,算法分析的两个主要方面是 A 。(1)A.找出数据结构的合理性B.研究算法中的输入和输出的关系C.分析算法的效率以求改进C.分析算法的易读性和文档性(2)A.空间复杂度和时间复杂度B.正确性和简明性 C.可读性和文档性D.数据复杂性和程序复杂性 8.下面程序段的时间复杂度是O(n2) 。 s =0; for( I =0; i

数据结构第七章图

数据结构习题(图) 一、选择题 1.设完全无向图的顶点个数为n,则该图有( B )条边。 A. n-l B. n(n-l)/2 C.n(n+l)/2 D. n(n-l) 2.在一个无向图中,所有顶点的度数之和等于所有边数的( )倍。 A.3 B.2 C.1 D.1/2 3.有向图的一个顶点的度为该顶点的( )。 A.入度 B. 出度 C.入度与出度之和 D.(入度+出度)/2 4.在无向图G (V,E)中,如果图中任意两个顶点vi、vj (vi、vj∈V,vi≠vj)都的,则称该图是( )。 A.强连通图 B.连通图 C.非连通图 D.非强连通图 5.若采用邻接矩阵存储具有n个顶点的一个无向图,则该邻接矩阵是一个( )。 A.上三角矩阵 B.稀疏矩阵 C.对角矩阵 D.对称矩阵 6.若采用邻接矩阵存储具有n个顶点的一个有向图,顶点vi的出度等于邻接矩阵 A.第i列元素之和 B.第i行元素之和减去第i列元素之和 C.第i行元素之和 D.第i行元素之和加上第i列元素之和 7.对于具有e条边的无向图,它的邻接表中有( )个边结点。 A.e-l B.e C.2(e-l) D. 2e 8.对于含有n个顶点和e条边的无向连通图,利用普里姆Prim算法产生最小生成时间复杂性为( ),利用克鲁斯卡尔Kruskal算法产生最小生成树(假设边已经按权的次序排序),其时间复杂性为( )。 A. O(n2) B. O(n*e) C. O(n*logn) D.O(e) 9.对于一个具有n个顶点和e条边的有向图,拓扑排序总的时间花费为O( ) A.n B.n+l C.n-l D.n+e 10.在一个带权连通图G中,权值最小的边一定包含在G的( )生成树中。 A.最小 B.任何 C.广度优先 D.深度优先 二、填空题 1.在一个具有n个顶点的无向完全图中,包含有____条边;在一个具有n个有向完全图中,包含有____条边。 2.对于无向图,顶点vi的度等于其邻接矩阵____ 的元素之和。 3.对于一个具有n个顶点和e条边的无向图,在其邻接表中,含有____个边对于一个具有n个顶点和e条边的有向图,在其邻接表中,含有_______个弧结点。 4.十字链表是有向图的另一种链式存储结构,实际上是将_______和_______结合起来的一种链表。 5.在构造最小生成树时,克鲁斯卡尔算法是一种按_______的次序选择合适的边来构造最小生成树的方法;普里姆算法是按逐个将_______的方式来构造最小生成树的另一种方法。 6.对用邻接表表示的图进行深度优先遍历时,其时间复杂度为一;对用邻接表表示的图进行广度优先遍历时,其时间复杂度为_______。 7.对于一个具有n个顶点和e条边的连通图,其生成树中的顶点数为_______ ,边数为_______。 8.在执行拓扑排序的过程中,当某个顶点的入度为零时,就将此顶点输出,同时将该顶点的所有后继顶点的入度减1。为了避免重复检测顶点的入度是否为零,需要设立一个____来存放入度为零的顶点。 三、简答题 l.回答以下问题:

数据结构(C语言版)期末复习

数据结构(C语言版)期末复习汇总 第一章绪论 数据结构:是一门研究非数值计算程序设计中的操作对象,以及这些对象之间的关系和操作的学科。 数据结构分为:逻辑结构、物理结构、操作三部分 逻辑结构:集合、线性结构、树形结构、图(网)状结构 物理结构(存储结构):顺序存储结构、链式存储结构 算法:是为了解决某类问题而规定的一个有限长的操作序列。 算法五个特性:有穷性、确定性、可行性、输入、输出 评价算法优劣的基本标准(4个):正确性、可读性、健壮性、高效性及低存储量 语句频度的计算。 算法的时间复杂度: 常见有:O(1),O(n),O(n2),O(log2n),O(nlog2n),O(2n) 第二章线性表 线性表的定义和特点: 线性表:由n(n≥0)个数据特性相同的元素构成的有限序列。线性表中元素个数n(n≥0)定义为线性表的长度,n=0时称为空表。 非空线性表或线性结构,其特点: (1)存在唯一的一个被称作“第一个”的数据元素; (2)存在唯一的一个被称作“最有一个”的数据元素; (3)除第一个之外,结构中的每个数据元素均只有一个前驱; (4)除最后一个之外,结构中的每个数据元素均只有一个后继。 顺序表的插入:共计n个元素,在第i位插入,应移动(n-i+1)位元素。 顺序表的删除:共计n个元素,删除第i位,应移动(n-i)位元素。 线性表的两种存储方式:顺序存储、链式存储。 顺序存储 概念:以一组连续的存储空间存放线性表; 优点:逻辑相邻,物理相邻;可随机存取任一元素;存储空间使用紧凑; 缺点:插入、删除操作需要移动大量的元素;预先分配空间需按最大空间分配,利用不充分;表容量难以扩充; 操作:查找、插入、删除等 查找: ListSearch(SqlList L,ElemType x,int n) { int i; for (i=0;i

数据结构第7章 图习题

第7章图 一、单项选择题 1.在一个无向图G中,所有顶点的度数之和等于所有边数之和的______倍。 A.l/2 B.1 C.2 D.4 2.在一个有向图中,所有顶点的入度之和等于所有顶点的出度之和的______倍。 A.l/2 B.1 C.2 D.4 3.一个具有n个顶点的无向图最多包含______条边。 A.n B.n+1 C.n-1 D.n(n-1)/2 4.一个具有n个顶点的无向完全图包含______条边。 A.n(n-l) B.n(n+l) C.n(n-l)/2 D.n(n-l)/2 5.一个具有n个顶点的有向完全图包含______条边。 A.n(n-1) B.n(n+l) C.n(n-l)/2 D.n(n+l)/2 6.对于具有n个顶点的图,若采用邻接矩阵表示,则该矩阵的大小为______。 A.n B.n×n C.n-1 D.(n-l) ×(n-l) 7.无向图的邻接矩阵是一个______。 A.对称矩阵B.零矩阵 C.上三角矩阵D.对角矩阵 8.对于一个具有n个顶点和e条边的无(有)向图,若采用邻接表表示,则表头向量的大小为______。 A.n B.e C.2n D.2e 9.对于一个具有n个顶点和e条边的无(有)向图,若采用邻接表表示,则所有顶点邻接表中的结点总数为______。

A.n B.e C.2n D.2e 10.在有向图的邻接表中,每个顶点邻接表链接着该顶点所有______邻接点。 A.入边B.出边 C.入边和出边D.不是入边也不是出边 11.在有向图的逆邻接表中,每个顶点邻接表链接着该顶点所有______邻接点。 A.入边B.出边 C.入边和出边D.不是人边也不是出边 12.如果从无向图的任一顶点出发进行一次深度优先搜索即可访问所有顶点,则该图一定是______。 A.完全图B.连通图 C.有回路D.一棵树 13.采用邻接表存储的图的深度优先遍历算法类似于二叉树的______算法。 A.先序遍历B.中序遍历 C.后序遍历 D.按层遍历 14.采用邻接表存储的图的广度优先遍历算法类似于二叉树的______算法。 A.先序遍历B.中序遍历 C.后序遍历 D.按层遍历 15.如果无向图G必须进行二次广度优先搜索才能访问其所有顶点,则下列说法中不正确的是______。 A.G肯定不是完全图B.G一定不是连通图 C.G中一定有回路D.G有二个连通分量 16.下列有关图遍历的说法不正确的是______。 A.连通图的深度优先搜索是一个递归过程 B.图的广度优先搜索中邻接点的寻找具有“先进先出”的特征 C.非连通图不能用深度优先搜索法 D.图的遍历要求每一顶点仅被访问一次 17.下列说法中不正确的是______。 A.无向图中的极大连通子图称为连通分量

数据结构第七章图练习及答案

1.拓扑排序的结果不是唯一的,试写出下图任意2个不同的拓扑序列。 2.写出求以下AOE网的关键路径的过程。要求:给出每一个事件和每一个活动的最早开 始时间和最晚开始时间。 【解析】解题关键是弄清拓扑排序的步骤 (1)在AOV网中,选一个没有前驱的结点且输出;(2)删除该顶点和以它为尾的弧;(3)重复上述步骤直至全部顶点均输出或不再有无前驱的顶点。 【答案】(1)0132465 (2)0123465 【解析】求关键路径首先求关键活动,关键活动ai的求解过程如下 (1)求事件的最早发生时间ve(j), 最晚发生时间vl(j); (2)最早发生时间从ve(0)开始按拓扑排序向前递推到ve(6), 最晚发生时间从vl(6)按逆拓扑排序向后递推到vl(0); (3)计算e(i),l(i):设ai由弧表示,持续时间记为dut,则有下式成立 e(i)=ve(j) l(i)=vl(k)-dut() (4)找出e(i)-l(i)=0的活动既是关键活动。 【答案】

关键路径为:a0->a4->a6->a9 7.1选择题 1.对于一个具有n个顶点和e条边的有向图,在用邻接表表示图时,拓扑排序算法时间复杂度为(B) A)O(n) B)O(n+e) C)O(n*n) D)O(n*n*n) 2.设无向图的顶点个数为n,则该图最多有(B)条边。 A)n-1 B)n(n-1)/2 C)n(n+1)/2 D)n2 3.连通分量指的是(B) A)无向图中的极小连通子图 B)无向图中的极大连通子图 C)有向图中的极小连通子图 D)有向图中的极大连通子图 4.n个结点的完全有向图含有边的数目(D) A)n*n B)n(n+1) C)n/2 D)n*(n-1) 5.关键路径是(A) A)AOE网中从源点到汇点的最长路径 B)AOE网中从源点到汇点的最短路径 C)AOV网中从源点到汇点的最长路径 D)AOV网中从源点到汇点的最短路径 6.有向图中一个顶点的度是该顶点的(C) A)入度B)出度C)入度与出度之和D)(入度+出度)/2 7.有e条边的无向图,若用邻接表存储,表中有(B)边结点。 A) e B)2e C)e-1 D)2(e-1) 8.实现图的广度优先搜索算法需使用的辅助数据结构为(B)

数据结构第七章图练习及答案

数据结构第七章图练习及答案 1( 拓扑排序的结果不是唯一的,试写出下图任意2个不同的拓扑序列。 2(写出求以下AOE网的关键路径的过程。要求:给出每一个事件和每一个活动的最早开始时间和最晚开始时间。 【解析】解题关键是弄清拓扑排序的步骤 (1)在AOV网中,选一个没有前驱的结点且输出;(2)删除该顶点和以它为尾的弧;(3)重复上述步骤直至全部顶点均输出或不再有无前驱的顶点。 【答案】(1)0132465 (2)0123465 【解析】求关键路径首先求关键活动,关键活动ai的求解过程如下 (1)求事件的最早发生时间ve(j), 最晚发生时间vl(j); (2)最早发生时间从ve(0)开始按拓扑排序向前递推到ve(6), 最晚发生时间从vl(6)按逆拓扑排序向后递推到 vl(0); (3)计算e(i),l(i):设ai由弧表示,持续时间记为dut,则有下式成立 e(i)=ve(j) l(i)=vl(k)-dut()

(4)找出e(i)-l(i)=0的活动既是关键活动。 【答案】 关键路径为:a0->a4->a6->a9 7.1 选择题 1(对于一个具有n个顶点和e条边的有向图,在用邻接表表示图时,拓扑排序算法时间复 杂度为( B ) A) O(n) B) O(n+e) C) O(n*n) D) O(n*n*n) 2(设无向图的顶点个数为n,则该图最多有( B )条边。 A)n-1 B)n(n-1)/2 C) n(n+1)/2 D)n2 3(连通分量指的是( B ) A) 无向图中的极小连通子图 B) 无向图中的极大连通子图 C) 有向图中的极小连通子图 D) 有向图中的极大连通子图 4(n个结点的完全有向图含有边的数目( D ) A)n*n B)n(n+1) C)n/2 D)n*(n-1) 5(关键路径是( A ) A) AOE网中从源点到汇点的最长路径

数据结构第7章 图习题

习题7 图 单项选择题 1.在一个图中,所有顶点的度数之和等于所有边数的____倍。 A. 1/2 B. 1 C. 2 D. 4 2.任何一个无向连通图的最小生成树。 A.只有一棵 B.有一棵或多棵 C.一定有多棵 D.可能不存在 3.在一个有向图中,所有顶点的入度之和等于所有顶点的出度之和的____倍。 A. 1/2 B. 1 C. 2 D. 4 4.一个有n个顶点的无向图最多有____条边。 A. n B. n(n-1) C. n(n-1)/2 D. 2n 5.具有4个顶点的无向完全图有____条边。 A. 6 B. 12 C. 16 D. 20 6.具有6个顶点的无向图至少应有____条边才能确保是一个连通图。 A. 5 B. 6 C. 7 D. 8 7.在一个具有n个顶点的无向图中,要连通全部顶点至少需要____条边。 A. n B. n+1 C. n-1 D. n/2 8.对于一个具有n个顶点的无向图,若采用邻接矩阵表示,则该矩阵的大小是____。 A. n B. (n-1)2 C. n-1 D. n2 9.对于一个具有n个顶点和e条边的无向图,若采用邻接表表示,则表头向量的大小为_①___;所有邻接表中的接点总数是_②___。 ①A. n B. n+1 C. n-1 D. n+e ② A. e/2 B. e D. n+e 10.已知一个图如图所示,若从顶点a出发按深度搜索法进行遍历,则可能得到 的一种顶点序列为__①__;按宽度搜索法进行遍历,则可能得到的一种顶点序列 为__②__。 ① A. a,b,e,c,d,f B. e,c,f,e,b,d C. a,e,b,c,f,d D. a,e,d,f,c,b ② A. a,b,c,e,d,f B. a,b,c,e,f,d C. a,e,b,c,f,d D. a,c,f,d,e,b

《数据结构(C语言描述)》期末试卷要点

专业 《数据结构(C 语言描述)》期末试卷 ( — 学年 第 学期) 一、填空(10分) 1、一个m 阶B-树中,每个结点最少有( ceil(m/2) )个儿子结点,m 阶B+树中每个结点(除根外)最多有( m )个儿子结点. 2、n(n>0)个结点构成的二叉树,叶结点最多有( floor((n+1)/2) )个,最少有( 1 )个。若二叉树有m 个叶结点,则度为2的结点有( m-1 )个。 3、顺序查找方法适用于存储结构为( 顺序表和线性链表 )的线性表,使用折半查找方法的条件是(查找表为顺序存贮的有序表 ) 4、广义表A=(( ),(a ,(b ,c)),d)的表尾Gettail(A)为( ((a,(b,c)),d) ) 5、直接插入排序,起泡排序和快速排序三种方法中,( 快速排序 )所需的平均执行时间最小;( 快速排序 )所需附加空间最大。 二、选择(10分) 1、倒排文件的主要优点是:( C ) A 、便于进行插入和删除 B 、便于进行文件的合并 C 、能大大提高基于非主关键字数据项的查找速度 D 、易于针对主关键字的逆向检索 2 下面程序段的时间复杂性为( C ) y=0; while(n>=(y+1)*(y+1)) { y++; } A 、O(n) B 、O(n 2) C 、 O(sqrt(n)) D 、 O(1) 3、若从二叉树的任一结点出发到根的路径上所经过的结点序列按其关键字有序,则该二叉树是( C ) A 、二叉排序树 B 、哈夫曼树 C 、堆 D 、AVL 树 4、栈和队列都是( B ) A 、顺序存储的线性结构 B 、限制存取点的线性结构 C 、链式存储的线性结构 D 、限制存取点的非线性结构 5、用顺序查找方法查找长度为n 的线性表时,在等概率情况下的平均查找长度为( D ) A 、n B 、n/2 C 、(n-1)/2 D 、(n+1)/2 三、简答(30分) 1、已知一棵二叉树的前序扫描序列和中序扫描序列分别为ABCDEFGHIJ 和BCDAFEHJIG ,试给出该二叉树的后序序列并绘出该二叉树对应的森林。 院(系) 班级 姓名 学号 ……………………………………………装…………………………订………………………线……………………………………………

数据结构(c语言版)复习资料

数据结构复习资料 一、填空题 1. 数据结构是一门研究非数值计算的程序设计问题中计算机的操作对象以及它们之间的关系和运算等的学科。 2. 数据结构被形式地定义为(D, R),其中D是数据元素的有限集合,R是D上的关系有限集合。 3. 数据结构包括数据的逻辑结构、数据的存储结构和数据的运算这三个方面的内容。 4. 数据结构按逻辑结构可分为两大类,它们分别是线性结构和非线性结构。 5. 线性结构中元素之间存在一对一关系,树形结构中元素之间存在一对多关系,图形结构中元素之间存在多对多关系。 6.在线性结构中,第一个结点没有前驱结点,其余每个结点有且只有 1个前驱结点;最后一个结点没有后续结点,其余每个结点有且只有1个后续结点。 7. 在树形结构中,树根结点没有前驱结点,其余每个结点有且只有 1个前驱结点;叶子结点没有后续结点,其余每个结点的后续结点数可以任意多个。 8. 在图形结构中,每个结点的前驱结点数和后续结点数可以任意多个。 9.数据的存储结构可用四种基本的存储方法表示,它们分别是顺序、链式、索引和散列。 10. 数据的运算最常用的有5种,它们分别是插入、删除、修改、查找、排序。 11. 一个算法的效率可分为时间效率和空间效率。

12. 在顺序表中插入或删除一个元素,需要平均移动表中一半元素,具体移动的元素个数与表长和该元素在表中的位置有关。 13. 线性表中结点的集合是有限的,结点间的关系是一对一的。 14. 向一个长度为n的向量的第i个元素(1≤i≤n+1)之前插入一个元素时,需向后移动n-i+1 个元素。 15. 向一个长度为n的向量中删除第i个元素(1≤i≤n)时,需向前移动n-i 个元素。 16. 在顺序表中访问任意一结点的时间复杂度均为 O(1),因此,顺序表也称为随机存取的数据结构。 17. 顺序表中逻辑上相邻的元素的物理位置必定相邻。单链表中逻辑上相邻的元素的物理位置不一定相邻。 18.在单链表中,除了首元结点外,任一结点的存储位置由其直接前驱结点的链域的值指示。 19.在n个结点的单链表中要删除已知结点*p,需找到它的前驱结点的地址,其时间复杂度为O(n)。 20. 向量、栈和队列都是线性结构,可以在向量的任何位置插入和删除元素;对于栈只能在栈顶插入和删除元素;对于队列只能在队尾插入和队首删除元素。 21. 栈是一种特殊的线性表,允许插入和删除运算的一端称为栈顶。不允许插入和删除运算的一端称为栈底。 22. 队列是被限定为只能在表的一端进行插入运算,在表的另一端进行删除运算的线性表。 23. 不包含任何字符(长度为0)的串称为空串;由一个或多个空格(仅由空格符)组成的串称为空白串。 24. 子串的定位运算称为串的模式匹配;被匹配的主串称为目标串,子串称为模式。

数据结构c语言版期末考试复习试题

《数据结构与算法》复习题一、选择题。 1.在数据结构中,从逻辑上可以把数据结构分为 C 。 A.动态结构和静态结构B.紧凑结构和非紧凑结构 C.线性结构和非线性结构D.内部结构和外部结构 2.数据结构在计算机内存中的表示是指 A 。 A.数据的存储结构B.数据结构C.数据的逻辑结构D.数据元素之间的关系3.在数据结构中,与所使用的计算机无关的是数据的 A 结构。 A.逻辑B.存储C.逻辑和存储D.物理 4.在存储数据时,通常不仅要存储各数据元素的值,而且还要存储 C 。 A.数据的处理方法B.数据元素的类型 C.数据元素之间的关系D.数据的存储方法 5.在决定选取何种存储结构时,一般不考虑 A 。 A.各结点的值如何B.结点个数的多少 C.对数据有哪些运算D.所用的编程语言实现这种结构是否方便。 6.以下说法正确的是 D 。 A.数据项是数据的基本单位 B.数据元素是数据的最小单位 C.数据结构是带结构的数据项的集合 D.一些表面上很不相同的数据可以有相同的逻辑结构 7.算法分析的目的是 C ,算法分析的两个主要方面是 A 。 (1)A.找出数据结构的合理性B.研究算法中的输入和输出的关系C.分析算法的效率以求改进C.分析算法的易读性和文档性 (2)A.空间复杂度和时间复杂度B.正确性和简明性 C.可读性和文档性D.数据复杂性和程序复杂性 8.下面程序段的时间复杂度是O(n2) 。 s =0; for( I =0; i

数据结构第七章图练习及答案

一、选择题 1、有6个结点的有向完全图有()条弧。 A、36 B、28 C、30 D、15 2、用邻接表表示图进行广度优先遍历时,通常采用()来实现算法。 A、栈 B、队列 C、树 D、图 3、用邻接表表示图进行深度优先遍历时,通常采用()来实现算法。 A、栈 B、队列 C、树 D、图 4、任何一个无向连通图的最小生成树() A、只有一棵 B、一棵或多棵 C、一定有多棵 D、可能不存在5、在一个图中,所有顶点的度数之和等于所有边数和的()倍。 A、B、1C、2D、4 6、在一个有向图中,所有顶点的入度之和等于所有顶点的出度之和的()倍。 A、B、1C、2D、4 7、一个有n个顶点的无向图最多有()条边。 A、n B、n(n-1) C、n(n-1)/2 D、2n 8、具有5个顶点的无向完全图有()条边。 A、6 B、8 C、10 D、20 9、在一个具有n个顶点的无向图中,要连通全部顶点至少需要()条边。 A、n B、n+1 C、n-1 D、n/2 10、对于一个具有n个顶点的无向图,若采用邻接矩阵表示,则该矩阵的大小是()A、(n+1)*(n-1)B、(n-1)*(n-1)C、n D、n*n

11、对于一个具有n个顶点和e条边的无向图,若采用邻接表表示,则表头向量的大小为(),所有邻接表中的结点总数是() (1)A、n B、n+1C、n-1D、n+e (2)A、e/2B、e C、2eD、n+e 12、采用邻接表存储的图的深度优先遍历算法类似于二叉树的() A、先序遍历 B、中序遍历 C、后序遍历 D、按层遍历 13、采用邻接表存储的图的广度优先遍历算法类似于二叉树的() A、先序遍历 B、中序遍历 C、后序遍历 D、按层遍历 14、判定一个有向图是否存在回路,除了利用拓扑排序方法外,还可以利用()A、求关键路径的方法B、求最短路径的方法 C、宽度优先遍历算法 D、深度优先遍历算法 15、关键路径是AOE网中的() A、从源点到汇点的最长路径 B、从源点到汇点的最短路径 C、最短的回路 D、活动的最早开始时间与最迟发生时间相等 二、填空题 1、有向图G用邻接矩阵存储,则其第i行的所有元素之和等于顶点i的(出度)。 2、设有一稀罕图G,则G采用(邻接表)存储较省空间。 3、设有一粘稠图G,则G采用(邻接矩阵)存储较省空间。 4、图的邻接表存储结构只适用于()图。 5、已知一个图的邻接矩阵表示,删除所有从第i个顶点出发的边的方法是(访问矩阵第I行)。

数据结构教案C语言版

数据结构教案C语言版 Last updated on the afternoon of January 3, 2021

课程教案 课程名称:数据结构 授课教师: 学习对象: 任课时间: 一、学生情况分析 数据结构是计算机专业的一门核心专业课程。学生在前期的学习中已经学习了C语言程序设计课程。通过本课程学习使学生对提高编写程序的能力以及解决实际问题的能力。 二、课程教学目标 《数据结构》是计算机学科中一门核心专业基础课。主要介绍如何合理地组织数据、有效地存储和处理数据,正确地设计算法以及对算法的分析和评价。通过本课程的学习,使学生深透地理解数据结构的逻辑结构和物理结构的基本概念以及有关算法,培养基本的、良好的程序设计技能,编制高效可靠的程序,为学习操作系统、编译原理和数据库等课程奠定基础。 三、课程教学内容 第一章绪论 教学内容: 1)什么是数据结构

2)抽象数据类型概念;数据类型;数据抽象与抽象数据类型;用于描述数据结构的语言 3)数据结构的抽象层次 4)算法定义 5)性能分析与度量;算法的性能标准;算法的后期测试;算法的事前估计;空间复杂度度量;时间复杂度度量;时间复杂度的渐进表示法; 教学要求: 了解:数据结构基本概念及数据结构的抽象层次 了解:抽象数据类型概念 了解:算法的定义及算法特性 掌握:算法的性能分析与度量方法 第二章线性表 教学内容: 1)线性表的定义和特点 2)线性表的顺序存储及查找、插入和删除操作 3)线性表的链式存储及查找、插入和删除操作 4)使用线性表的实例 教学要求: 了解:线性表的定义和特点 熟练掌握:线性表的顺序存储结构的查找、插入和删除等基本操作 熟练掌握:单链表、循环链表及双向链表的定义及实现 掌握:熟练掌握单链表的应用方法

严蔚敏数据结构题集C语言版完整答案

严蔚敏 数据结构C 语言版答案详解 第1章 绪论 1.1 简述下列术语:数据,数据元素、数据对象、数据结构、存储结构、数据类型和抽象数据类型。 解:数据是对客观事物的符号表示。在计算机科学中是指所有能输入到计算机中并被计算机程序处理的符号的总称。 数据元素是数据的基本单位,在计算机程序中通常作为一个整体进行考虑和处理。 数据对象是性质相同的数据元素的集合,是数据的一个子集。 数据结构是相互之间存在一种或多种特定关系的数据元素的集合。 存储结构是数据结构在计算机中的表示。 数据类型是一个值的集合和定义在这个值集上的一组操作的总称。 抽象数据类型是指一个数学模型以及定义在该模型上的一组操作。是对一般数据类型的扩展。 1.2 试描述数据结构和抽象数据类型的概念与程序设计语言中数据类型概念的区别。 解:抽象数据类型包含一般数据类型的概念,但含义比一般数据类型更广、更抽象。一般数据类型由具体语言系统内部定义,直接提供给编程者定义用户数据,因此称它们为预定义数据类型。抽象数据类型通常由编程者定义,包括定义它所使用的数据和在这些数据上所进行的操作。在定义抽象数据类型中的数据部分和操作部分时,要求只定义到数据的逻辑结构和操作说明,不考虑数据的存储结构和操作的具体实现,这样抽象层次更高,更能为其他用户提供良好的使用接口。 1.3 设有数据结构(D,R),其中 {}4,3,2,1d d d d D =,{}r R =,()()(){}4,3,3,2,2,1d d d d d d r = 试按图论中图的画法惯例画出其逻辑结构图。 解: 1.4 试仿照三元组的抽象数据类型分别写出抽象数据类型复数和有理数的定义(有理数是其分子、分母均为自然数且分母不为零的分数)。 解: ADT Complex{ 数据对象:D={r,i|r,i 为实数} 数据关系:R={} 基本操作: InitComplex(&C,re,im) 操作结果:构造一个复数C ,其实部和虚部分别为re 和im DestroyCmoplex(&C) 操作结果:销毁复数C Get(C,k,&e) 操作结果:用e 返回复数C 的第k 元的值 Put(&C,k,e) 操作结果:改变复数C 的第k 元的值为e

数据结构第7章 图习题

习题7 图 7.1 单项选择题 1.在一个图中,所有顶点的度数之和等于所有边数的____倍。 A. 1/2 B. 1 C. 2 D. 4 2.任何一个无向连通图的最小生成树。 A.只有一棵 B.有一棵或多棵 C.一定有多棵 D.可能不存在 3.在一个有向图中,所有顶点的入度之和等于所有顶点的出度之和的____倍。 A. 1/2 B. 1 C. 2 D. 4 4.一个有n个顶点的无向图最多有____条边。 A. n B. n(n-1) C. n(n-1)/2 D. 2n 5.具有4个顶点的无向完全图有____条边。 A. 6 B. 12 C. 16 D. 20 6.具有6个顶点的无向图至少应有____条边才能确保是一个连通图。 A. 5 B. 6 C. 7 D. 8 7.在一个具有n个顶点的无向图中,要连通全部顶点至少需要____条边。 A. n B. n+1 C. n-1 D. n/2 8.对于一个具有n个顶点的无向图,若采用邻接矩阵表示,则该矩阵的大小是____。 A. n B. (n-1)2 C. n-1 D. n2 9.对于一个具有n个顶点和e条边的无向图,若采用邻接表表示,则表头向量的大小为_①___;所有邻接表中的接点总数是_②___。 ①A. n B. n+1 C. n-1 D. n+e ②A. e/2 B. e C.2e D. n+e 10.已知一个图如图7.1所示,若从顶点a出发按深度搜索法进行遍历,则可能得到的一种顶点序列为__①__;按宽度搜索法进行遍历,则可能得到的一种顶点序列 为__②__。 ①A. a,b,e,c,d,f B. e,c,f,e,b,d C. a,e,b,c,f,d D. a,e,d,f,c,b ②A. a,b,c,e,d,f B. a,b,c,e,f,d C. a,e,b,c,f,d D. a,c,f,d,e,b 图 7.1 一个无向图 11.已知一有向图的邻接表存储结构如图7.2所示。

数据结构(c语言版)第1章习题答案

1 第一章概论 自测题答案 一、填空题 1. 数据结构是一门研究非数值计算的程序设计问题中计算机的 操作对象 以及它们之间的 关系 和运算等的学科。 2. 数据结构被形式地定义为(D, R ),其中D 是 数据元素 的有限集合,R 是D 上的 关系 有限集合。 3. 数据结构包括数据的 逻辑结构 、数据的 存储结构 和数据的 运算 这三个方面的内容。 4. 数据结构按逻辑结构可分为两大类,它们分别是 线性结构 和 非线性结构 。 5. 线性结构中元素之间存在一对一关系,树形结构中元素之间存在一对多关系,图形结构中元素之间存在多对多关系。 6. 在线性结构中,第一个结点 没有 前驱结点,其余每个结点有且只有 1个前驱结点;最后一个结点 没有 后续结点,其余每个结点有且只有1个后续结点。 7. 在树形结构中,树根结点没有 前驱 结点,其余每个结点有且只有 1 个前驱结点;叶子结点没有 后续 结点,其余每个结点的后续结点数可以任意多个 。 8. 在图形结构中,每个结点的前驱结点数和后续结点数可以 任意多个 。 9.数据的存储结构可用四种基本的存储方法表示,它们分别是顺序 、 链式 、 索引 和 散列 。 10. 数据的运算最常用的有5种,它们分别是插入 、 删除、修改、 查找 、排序。 11. 一个算法的效率可分为 时间 效率和 空间 效率。 二、单项选择题 ( B )1. 非线性结构是数据元素之间存在一种: A )一对多关系 B )多对多关系 C )多对一关系 D )一对一关系 ( C )2. 数据结构中,与所使用的计算机无关的是数据的 结构; A) 存储 B) 物理 C) 逻辑 D) 物理和存储 ( C )3. 算法分析的目的是: A) 找出数据结构的合理性 B) 研究算法中的输入和输出的关系 C) 分析算法的效率以求改进 D) 分析算法的易懂性和文档性 ( A )4. 算法分析的两个主要方面是: A) 空间复杂性和时间复杂性 B) 正确性和简明性 C) 可读性和文档性 D) 数据复杂性和程序复杂性 ( C )5. 计算机算法指的是: A) 计算方法 B) 排序方法 C) 解决问题的有限运算序列 D) 调度方法 ( B )6. 计算机算法必须具备输入、输出和 等5个特性。 A) 可行性、可移植性和可扩充性 B) 可行性、确定性和有穷性 C) 确定性、有穷性和稳定性 D) 易读性、稳定性和安全性 三、简答题 1.【严题集1.2②】数据结构和数据类型两个概念之间有区别吗? 答:简单地说,数据结构定义了一组按某些关系结合在一起的数组元素。数据类型不仅定义了一组带结构的数据元素,而且还在其上定义了一组操作。 2. 简述线性结构与非线性结构的不同点。 答:线性结构反映结点间的逻辑关系是 一对一的,非线性结构反映结点间的逻辑关系是多对多的。 四、【严题集1.8④】分析下面各程序段的时间复杂度 2. s=0; for i=0; i

数据结构-(严蔚敏C语言版)-学习、复习提纲知识讲解

期末复习 第一章 绪论 复习 1、计算机算法必须具备输入、输出、可行性、确定性、有穷性5个特性。 2、算法分析的两个主要方面是空间复杂度和时间复杂度。 3、数据元素是数据的基本单位。 4、数据项是数据的最小单位。 5、数据结构是带结构的数据元素的集合。 6、数据的存储结构包括顺序、链接、散列和索引四种基本类型。 数据结构 算 法 数据:计算机处理的信息总称 数据项:最小单位 数据元素:最基本单位 数据对象:元素集合 数据结构:相互之间存在一种或 多种特定关系的数据元素集合。 概念:数据元素之间的关系 线性结构:一对一 非线性结构 树:一对多 图:多对多 顺序存储结构 链表存储结构 索引。。。 散列。。。 算法描述:指令的有限有序序列 有穷性 确定性 可行性 输入 输出 时间复杂度 空间复杂度

第二章 线性表 复习 1、在双链表中,每个结点有两个指针域,包括一个指向前驱结点的指针 、一个指向后继结点的指针 2、线性表采用顺序存储,必须占用一片连续的存储单元 3、线性表采用链式存储,便于进行插入和删除操作 4、线性表采用顺序存储和链式存储优缺点比较。 5、简单算法 第三章 栈和队列 复习 定义 逻辑关系:前趋 后继 节省空间 随机存取 插、删效率低 插入 删除

1、 栈和队列的异同点。 2、 栈和队列的基本运算 3、 出栈和出队 4、 基本运算 第四章 串 复习 存储结构 栈的概念:在一端操作的线性表 运算算法 栈的特点:先进后出 LIFO 初始化 进栈push 出栈 pop 顺序队列 循环队列 队列概念:在两端操作的线性表 假溢出 链队列 队列特点:先进先出 FIFO 基本运算 顺序: 链队: 队空:front=rear 队满:front=(rear+1)%MAXSIZE 队空: rear 初始化 判空 进队 出队 取队首元素

相关文档
最新文档