數據結構(C語言)第二版 第六章課後答案
1~5 C B B B C
6~10 B A B A A
11~15 D C C (D,D) B
1.選擇題
(1)在一個圖中,所有頂點的度數之和等於圖的邊數的(C)倍。
A. 1/2 B. 1 C. 2 D. 4
任意一條邊都對應2個度,所以度數總和是邊數總和的兩倍。
(2)在一個有向圖中,所有頂點的入度之和等於所有頂點的出度之和的(B)倍。
A. 1/2 B. 1 C. 2 D. 4
有向圖所有頂點的入度之和等於所有頂點的出度之和
(3)具有n 個頂點的有向圖最多有(B)條邊。
A. n B . n(n-1) C. n(n+1) D . n2
有向圖的邊有方向之分, 即爲從n個頂點中選取 2 個頂點有序排列, 結果爲n(n-1)
(4) n 個頂點的連通圖用鄰接距陣表示時,該距陣至少有(B) 個非零元素。
A. n B . 2(n-1) C. n/2D . n2
連通圖一定是無向圖,有向的叫做強連通圖,連通n個頂點,至少只需要n-1條邊就可以,由於無向圖的每條邊同時關聯兩個頂點,因此鄰接矩陣中每條邊被存儲了兩次,因此至少有2(n-1)個非零元素
(5) G 是一個非連通無向圖,共有28 條邊,則該圖至少有(C)個頂點。
A. 7 B . 8 C. 9 D . 10
8 個頂點的無向圖最多有8*7/2=28 條邊,再添加一個點即構成非連通無向圖,故至少有9 個頂點。
(6)若從無向圖的任意一個頂點出發進行一次深度優先搜索可以訪問圖中所有的頂點,則該圖一定是(B)圖。
A.非連通 B .連通 C.強連通 D .有向
即從該無向圖任意一個頂點出發有到各個頂點的路徑, 所以該無向圖是連通圖。
(7)下面(A)算法適合構造一個稠密圖G 的最小生成樹。
A. Prim 算法B . Kruskal 算法C. Floyd 算法D. Dijkstra 算法
Prim 算法適合構造一個稠密圖G 的最小生成樹, Kruskal 算法適合構造一個稀疏圖G 的最小生成樹。
(8)用鄰接表表示圖進行廣度優先遍歷時,通常藉助(B)來實現算法。
A.棧B. 隊列C. 樹D .圖
廣度優先遍歷通常藉助隊列來實現算法,深度優先遍歷通常藉助棧來實現算法。
(9)用鄰接表表示圖進行深度優先遍歷時,通常藉助(A)來實現算法。
A.棧B. 隊列C. 樹D .圖
廣度優先遍歷通常藉助隊列來實現算法,深度優先遍歷通常藉助棧來實現算法。
(10)圖的深度優先遍歷類似於二叉樹的(A) 。
A.先序遍歷B.中序遍歷C.後序遍歷D.層次遍歷
因爲圖的深度優先遍歷算法先訪問所在結點,再訪問它的鄰接點。與二叉樹的先序遍歷先訪問子樹的根結點,再訪問它的孩子結點(鄰接點)類似。
( 11)圖的廣度優先遍歷類似於二叉樹的(D) 。
A.先序遍歷B .中序遍歷C.後序遍歷D.層次遍歷
圖的廣度優先遍歷算法類似於二叉樹的按層次遍歷。
(12)圖的 BFS 生成樹的樹高比 DFS 生成樹的樹高(C) 。
A.小B.相等C.小或相等D.大或相等
對於一些特殊的圖,比如只有一個頂點的圖,其BFS 生成樹的樹高和DFS 生
成樹的樹高相等。一般的圖,根據圖的BFS 生成樹和DFS 樹的算法思想, BFS 生成樹的樹高比DFS 生成樹的樹高小。
(13)已知圖的鄰接矩陣如圖6.30 所示, 則從頂點v0 出發按深度優先遍歷的結果是(C)。
按深度優先遍歷:先訪問所在結點,再訪問它的鄰接點,訪問過的跳過找下一個未訪問的結點,直到訪問完所有的結點。即0-1-3-4-2-5-6
(14)已知圖的鄰接表如圖6.31 所示,則從頂點v0 出發按廣度優先遍歷的結果是(D) ,按深度優先遍歷的結果是(D) 。
(15)下面(B)方法可以判斷出一個有向圖是否有環。
A. 求最小生成樹B. 拓撲排序C. 求最短路徑D .求關鍵路徑
判斷有沒有環的方法
深度優先排序
廣度優先排序
拓撲排序
2.應用題
(1)已知圖6.32 所示的有向圖,請給出:
①每個頂點的入度和出度;
②鄰接矩陣;
③鄰接表;
④逆鄰接表。
答案:
(2)已知如圖6.33 所示的無向網,請給出:
①鄰接矩陣;
②鄰接表;
③最小生成樹
(3)已知圖的鄰接矩陣如圖6.34 所示。試分別畫出自頂點1 出發進行遍歷所得的深度優先生成樹和廣度優先生成樹。
(4)有向網如圖6.35 所示,試用迪傑斯特拉算法求出從頂點a 到其他各頂點間的最短路徑,完成表6.9 。
(5)試對圖6.36 所示的AOE- 網:
① 求這個工程最早可能在什麼時間結束;
②求每個活動的最早開始時間和最遲開始時間;
③確定哪些活動是關鍵活動
按拓撲有序的順序計算各個頂點的最早可能開始時間Ve 和最遲允許開始時間Vl。然後再計算各個活動的最早可能開始時間e 和最遲允許開始時間l ,根據l-e = 0? 來確定關鍵活動,從而確定關鍵路徑。
3.算法設計題
(1)分別以鄰接矩陣和鄰接表作爲存儲結構,實現以下圖的基本操作:
①增加一個新頂點v, InsertVex(G, v) ;
②刪除頂點v 及其相關的邊, DeleteVex(G , v);
③增加一條邊<v , w>, InsertArc(G , v, w);
④刪除一條邊<v , w>, DeleteArc(G , v, w) 。
[ 算法描述]
//以鄰接矩陣作爲存儲結構
//增加一個新頂點v
Status Insert_Vex(MGraph &G, char v){
if((G.vexnum+1)>MAX_VERTEX_NUM) return INFEASIBLE;
G.vexs[++G.vexnum]=v;
return OK;
}
//刪除頂點v 及其相關的邊,
Status Delete_Vex(MGraph &G,char v){
n=G.vexnum;
if((m=LocateVex(G,v))<0) return ERROR;
G.vexs[m]<->G.vexs[n]; // 將待刪除頂點交換到最後一個頂點
for(i=0;i<n;i++){
G.arcs[m]=G.arcs[n];
G.arcs[m]=G.arcs[n]; // 將邊的關係隨之交換
}
G.arcs[m][m].adj=0;
G.vexnum--;
return OK;
}
//增加一條邊<v , w>
Status Insert_Arc(MGraph &G,char v,char w){
if((i=LocateVex(G,v))<0) return ERROR;
if((j=LocateVex(G,w))<0) return ERROR;
if(i==j) return ERROR;
if(!G.arcs[j].adj){
G.arcs[j].adj=1;
G.arcnum++;
}
return OK;
}
//刪除一條邊<v , w>
Status Delete_Arc(MGraph &G,char v,char w){
if((i=LocateVex(G,v))<0) return ERROR;
if((j=LocateVex(G,w))<0) return ERROR;
if(G.arcs[j].adj){
G.arcs[j].adj=0;
G.arcnum--;
}
return OK;
}
//以鄰接表作爲存儲結構
Status Insert_Arc(ALGraph &G,char v,char w){
if((i=LocateVex(G,v))<0) return ERROR;
if((j=LocateVex(G,w))<0) return ERROR;
p=new ArcNode;
p->adjvex=j;p->nextarc=NULL;
if(!G.vertices.firstarc) G.vertices.firstarc=p;
else{
for(q=G.vertices.firstarc;q->q->nextarc;q=q->nextarc)
if(q->adjvex==j) return ERROR; // 邊已經存在
q->nextarc=p;
}
G.arcnum++;
return OK;
}
(2)一個連通圖採用鄰接表作爲存儲結構,設計一個算法,實現從頂點v 出發的深度優先遍歷的非遞歸過程。
[ 算法描述]
Void DFSn(Graph G,int v){ // 從第v 個頂點出發非遞歸實現深度優先遍歷圖G
Stack s;
SetEmpty(s);
Push(s,v);
While(!StackEmpty(s)){
Pop(s,k);
If(!visited[k]){
visited[k]=TRUE;
VisitFunc(k);
for(w=FirstAdjVex(G,k);w;w=NextAdjVex(G,k,w)){
if(!visited[w]&&w!=GetTop(s)) Push(s,w);
}
}
}
}
(3)設計一個算法,求圖G 中距離頂點v 的最短路徑長度最大的一個頂點,設v 可達其餘各個頂點。
[ 算法描述]
int ShortestPath _ MAX(AMGraph G,int v0){
n=G.vexnum;
for(v = 0; v<n;++v){
S[v] = false;
D[v] = G.arcs[v0][v];
if(D[v]< MaxInt) Path [v]=v0;
else Path [v]=-1;
}
S[v0]=true;
D[v0]=0;
for(i=1;i<n; ++i){
min= MaxInt;
for(w=0;w<n; ++w)
if(!S[w]&&D[w]<min){v=w; min=D[w];}
S[v]=true;
for(w=0;w<n; ++w)
if(!S[w]&&(D[v]+G.arcs[v][w]<D[w])){
D[w]=D[v]+G.arcs[v][w];
Path [w]=v;
}
}
Max=D[0];
m=0;
for(i=1;i<n;i++)
if(Max<D[i]) m=i;
return m;
}
(4)試基於圖的深度優先搜索策略寫一算法, 判別以鄰接表方式存儲的有向圖中是否存在由頂點v i 到頂點v j 的路徑( i≠ j )。
[ 算法描述]
int visited[MAXSIZE];
int level = 1;
int exist_path_DFS(ALGraph G,int i,int j){
if(i==j) return 1;
else{
visited[i]=1;
for(p=G.vertices[i].firstarc;p;p=p->nextarc , level--){
level++;
k=p->adjvex;
if(!visited[k]&&exist_path(k,j)) return 1;
}
}
if (level==1) return 0;
}
(5)採用鄰接表存儲結構,編寫一個算法,判別無向圖中任意給定的兩個頂點之間是否存在一條長度爲爲k 的簡單路徑。
[ 算法描述]
int visited[MAXSIZE];
int exist_path_len(ALGraph G,int i,int j,int 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;
}
visited[i]=0;
}
return 0;
}