資料結構 鄰接多重表

2021-07-31 16:21:20 字數 4158 閱讀 8819

上一節總結了有向圖的另外一種鏈式儲存結構—十字鍊錶,該節繼續總結無向圖的另一種鏈式儲存結構。

鄰接表雖然已經能夠很好地表示無向圖了,但是無向圖訪問或者刪除一條邊(vi,vj)時需要同時訪問兩個鍊錶i和j並分別找到對應的邊結點,這給針對圖的邊的操作(標記或刪除)帶來不便利。鄰接多重表因此而演變過來的。

鄰接多重表中,無向圖中的每乙個頂點分配乙個頂點結點,所有頂點結點構成乙個頂點陣列adjmultilist[num]。另外每條邊也分配乙個邊結點。

頂點結構如下所示:

其中data用來記錄頂點的資訊,firstedge用來表示依附於該頂點的第一條邊。

頂點陣列如下所示:

邊結點結構如下所示:

其中mark表示標誌位,用於標記該邊是否已經被訪問過;ivex和jvex表示該邊的兩個頂點在頂點陣列adjmultilist[num]中的位置;ilink和jlink分別表示指向依附於頂點ivex和jvex下一條邊的指標。

從上面的頂點和邊的結構來看,鄰接多重表和鄰接表的主要區別在於:鄰接多重表中的邊結點同時被鏈入對應邊頂點的鍊錶內(2條);鄰接表中的邊用兩個表結點表示。另外,鄰接多重表中的邊結點就表示一條邊,比較容易理解。

舉個例子。某無向圖如下圖所示:

當採用鄰接表表示該無向圖時,其鄰接表入下圖所示:

如上圖所示,圖中黃色標記的結點表示a-d之間的邊,在鄰接表中一條邊需要兩個結點表示。因此如果對於邊的操作(標記或者刪除)則需要訪問兩條鍊錶。

當採用鄰接多重表表示該無向圖時,其鄰接多重表入下圖所示:

如上圖所示,結點a-d 之間的邊,在鄰接多重表中只需要乙個邊結點既可以表示。另外,在該結構中,每個邊結點被鏈入了兩個不同的鍊錶。其中a-d之間的邊被鏈入了紅色和綠色標記的鍊錶中。如果需要訪問一條邊,則可以從該邊的兩個頂點結點中的任何乙個出發,遍歷依附於該頂點的邊構成的鍊錶即可。如果需要刪除一條邊,則只需要刪除乙個邊結點,但是需要修改這條邊依附的兩個頂點所對應的鍊錶。另外,需要注意的是,在無向圖中,邊結點中的

ivex

和jvex

鏈域與該邊所依附的頂點無關,即

ivex=0

,jvex=3

和ivex=3

,jvex=0

這都表示同一條邊

a-d,因此這給鍊錶的指標修改帶來一定的麻煩。

1、建立無向圖的鄰接多重表

輸入abcde五個頂點v=,然後輸入邊e=,建立如下無向圖:

**如下:

status createamlgraph(amlgraph &g, int vexnum)

cout

if(switch == 'y')

else

break;

} return 1;

}

2、列印無向圖的鄰接多重表

**如下:

status printamlgraph(amlgraph &g)

else

} cout

3、向無向圖中新增頂點

向無向圖中新增結點f。

**如下:

status insertnode(amlgraph &g, vertexnode node)

4、向無向圖中新增邊

向無向圖中新增邊a-c。

**如下:

void insertedgeaction(amlgraph &g, int index1, int index2)

else

q = g.adjmultilist[index2].firstedge;//相當於鍊錶的插入

if(!q)

else

}status insertedge(amlgraph &g, vertexnode node1, vertexnode node2)

5、刪除無向圖中的邊

刪除無線圖中的邊b-c。

**如下:

status deleteedgeaction(amlgraph &g, int index1, int index2)

preedge = curedge;

if(curedge->ivex ==index1)

curedge = curedge->ilink;

else

curedge = curedge->jlink;

} }if(!curedge)

return 1;

else if(count<=1)

else

else

} return 1;

}status deleteedge(amlgraph &g, vertexnode node1, vertexnode node2)

6、刪除無向圖中的頂點

刪除結點c。

**如下:

status deletenode(amlgraph &g, vertexnode node)edgenode;

typedef struct vertexnodevertexnode;

typedef structamlgraph;

int locatenode(amlgraph &g, vertexnode node)

cout

if(switch == 'y')

else

break;

} return 1;

}void insertedgeaction(amlgraph &g, int index1, int index2)

else

q = g.adjmultilist[index2].firstedge;//相當於鍊錶的插入

if(!q)

else

}status insertedge(amlgraph &g, vertexnode node1, vertexnode node2)

status printamlgraph(amlgraph &g)

else

} coutjvex == index2)||(curedge->ivex == index2&&curedge->jvex == index1))

preedge = curedge;

if(curedge->ivex ==index1)

curedge = curedge->ilink;

else

curedge = curedge->jlink;

} }if(!curedge)

return 1;

else if(count<=1)

else

else

} return 1;

}status deleteedge(amlgraph &g, vertexnode node1, vertexnode node2)

status deletenode(amlgraph &g, vertexnode node)

資料結構 鍊錶 鄰接表

在講解這個內容之前,先來回憶陣列能夠完成哪些操作 1 任意訪問乙個元素,時間複雜度為o 1 o 1 o 1 2 刪除乙個元素,要移動此後的所有元素,時間複雜度為o n o n o n 3 在任意位置之後增添乙個元素,要移動此後的所有元素,時間複雜度為o n o n o n 但如果我們的問題並不需要訪...

資料結構之DFS(鄰接表版)

圖的遍歷 是指從圖中的任一頂點出發,對圖中的所有頂點訪問一次且只訪問一次。圖的遍歷是圖的基本操作之一,很多需要對圖中每個頂點依次進行的操作都可以在遍歷中完成。圖的遍歷通常有深度優先搜尋和廣度優先搜尋。深度優先搜尋 depth first search 深度優先搜尋的基本思想如下 1 從圖中某個頂點v...

鄰接多重表C 實現

鄰接多重表是面向無向圖的另一種鏈式儲存結構,從邊出發構建整個圖,方便訪問標記,刪除邊等操作,儲存空間最少。易判斷頂點之間的關係。由於不知道頂點是在左邊ilink還是右邊jlink,所以需要進行一次查詢 while curedge j ai curedge jlink null if curedge ...