(1)G 是一個非連通無向圖,共有 28 條邊,則該圖至少有( C)
個頂點
A.7 B.8 C.9 D.10
8個頂點的無向圖最多有 8*7/2=28 條邊,再添加一個點即構
成非連通無向圖,故至少有 9 個頂點
(2)分別以鄰接矩陣和鄰接表作為存儲結構,實現以下圖的基本操
作:
① 增加一個新頂點 v,InsertVex(G, v);
② 刪除頂點 v 及其相關的邊,DeleteVex(G, v);
③ 增加一條邊<v,w>,InsertArc(G, v, w);
④ 刪除一條邊<v,w>,DeleteArc(G, v, w)
①增加一條邊
`Status insert_Arc(MGraph&G,char v,char w)
//在鄰接矩陣表示的圖G上插入邊 <v,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及其相關的邊-----
Status Delete_vex(MGraph &G,char v)//在鄰接矩陣表示的圖上刪除頂點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.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; }`
(3)一個連通圖采用鄰接表作為存儲結構,設計一個算法,實現從
頂點 v 出發的深度優先遍歷的非遞歸過程.
`Void DFSn(Graph G,int v)
{ //從第 v 個頂點出發非遞歸實現深度優先遍歷圖 G
Stack s;
SetEmpty(s);
Push(s,v);
While(!StackEmpty(s))
{ //棧空時第 v 個頂點所在的連通分量已遍歷完
Pop(s,k);
If(!visited[k])
{ visited[k]=TRUE;
VisitFunc(k); //訪問第 k 個頂點
//將第 k 個頂點的所有鄰接點進棧
for(w=FirstAdjVex(G,k);w;w=NextAdjVex(G,k,w))
{
if(!visited[w]&&w!=GetTop(s)) Push(s,w);
//圖中有環時 w==GetTop(s)
}
}
}`
(4)設計一個算法,求圖 G 中距離頂點 v 的最短路徑長度最大的一
個頂點,設 v 可達其余各個頂點。
分析:利用 Dijkstra 算法求 v0 到其它所有頂點的最短路徑,分別保存在
數組 D[i]中,然后求出 D[i]中值最大的數組下標 m 即可。
`int ShortestPath_MAX(AMGraph G, int v0)
{ //用 Dijkstra 算法求距離頂點 v0 的最短路徑長度最大的一個頂點 m
n=G.vexnum; //n 為 G 中頂點的個數
for(v = 0; v<n; ++v)
{ //n 個頂點依次初始化
S[v] = false; //S 初始為空集
D[v] = G.arcs[v0][v]; //將 v0 到各個終點的最短路徑長度初始化
if(D[v]< MaxInt) Path [v]=v0;//如果 v0 和 v 之間有弧,則將 v 的前驅置為 v0
else Path [v]=-1; //如果 v0 和 v 之間無弧,則將 v 的前驅置為 -1;
}
S[v0]=true; //將 v0 加入 S
D[v0]=0; //源點到源點的距離為0
/*開始主循環,每次求得 v0 到某個頂點 v 的最短路徑,將 v加到 S 集*/
for(i=1;i<n; ++i){ //對其余 n− 1 個頂點,依次進行計算
min= MaxInt;
for(w=0;w<n; ++w)
if(!S[w]&&D[w]<min)
{v=w; min=D[w];} //選擇一條當前的最短路徑,終點為 v
S[v]=true; //將 v 加入 S
for(w=0;w<n; ++w) //更新從 v0到 V− S 上所有頂點的最短路徑長度
if(!S[w]&&(D[v]+G.arcs[v][w]<D[w])){
D[w]=D[v]+G.arcs[v][w]; //更新 D[w]
Path [w]=v;//更改 w 的前驅為V
}
}
/*最短路徑求解完畢,設距離頂點 v0 的最短路徑長度最大的一個頂點為 m */
Max=D[0];
m=0;
for(i=1;i<n;i++)
if(Max<D[i]) m=i;
return m ;`
(5)采用鄰接表存儲結構,編寫一個算法,判別無向圖中任意給定的兩個頂點之間是否存在一條長度為為 k 的簡單路徑
`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]=l;
for(p=G.vertices[i].firstarc;p;p=p->nextarc) //鏈域(firstarc,nextarc),鄰接點域(adjvex)
{l=p->adjvex;
if(!visited[l])
if(exist_path_len(G,l,j,k-1)) return 1; //剩余路徑長度減一
}
visited[i]=0; //本題允許曾經被訪問過的結點出現在另一條路徑中
}//else
return 0; //沒找到
}`
