鄰接表不和鄰接矩陣只和點有若干聯絡,它和點與邊都有密切的聯絡。
鄰接表的實現需要四個東西,一個是記錄邊資訊的數組、一個是表頭、一個是當前操作邊的序號、一個是add函數。(當然也少不了初始化函數了)
具體如下。
int which=1;int head[maxv];struct EDGE{ int d,w,next; EDGE():next(-1){}}e[maxv];void add(int s, int d,int w){ e[which].d=d; e[which].w=w; e[which].next=head[s]; head[s]=which++;}void initforgraph(){ memset(head,-1,sizeof(head)); memset(e,0,sizeof(e));}
which表示當前操作的是哪一條邊(是邊的序號)(有些人喜歡用size、用n,其實都是習慣問題了。which到最後輸入結束的時候也是邊的數量)
head是表頭,head【2】表示以2為起點的邊的表。
e數組是記錄邊資訊的,但是由於鄰接表的特殊性,我們只需要記錄他的終點、權值和下一條邊的序號,而不是像克魯斯卡爾演算法中經典地儲存起點、終點、權值這樣子。
在插入邊表的時候是前叉式,所以代碼看上去好像是有點繞。
不瞭解前叉式建表的話建議先去看看鏈表的插入的幾種方式。
這裡注意下head一定要初始化為-1的。
不瞭解鄰接表的話,也比較難看懂代碼,建議學一下資料結構的圖的相關知識。
當然這種實現方式不是使用教科書上的指標的實現方式,而是用數組類比的。他們使用起來是一樣的效果。
下面是遍曆方式。
其實使用鄰接表的圖的遍曆方式很像是BFS,由一個點發散的遍曆他相鄰的點(邊)。
遍曆方式是基於我上面給出的鄰接表的實現方式的。
int main(){ initforgraph(); int t1,t2,t3; for(int i=1;i<=M;i++)//M is the number of edges. { scanf("%d%d%d",&t1,&t2,&t3);//start, end, weight. add(t1,t2,t3); } for(int i=1;i<=N;i++) { printf("起點是%d有\n",i); for(int j=head[i];j!=-1;j=e[j].next) { printf("編號為%d的邊\n",j); } printf("\n"); }}
下面的第一重迴圈是對所有的點進行迴圈,第二重迴圈是對以這個點為起點的所有的邊的迴圈。