【轉】圖的鄰接鏈表 adjacent list of graph


http://hi.baidu.com/fly_fireocean/item/0711568aa52f1acf99255ffc

鄰接鏈表(Adjacency List)是圖的一種鏈式存儲結構,與樹型結構中的孩子鏈表相似。通常鄰接鏈表也稱鄰接表。

1. 鄰接表的結點結構
邊結點結構

     鄰接表中每個表結點均有兩個域:
 ① 鄰接點域adjvex
  存放與vi相鄰接的頂點vj的序號j。
 ② 鏈域next
  將鄰接表的所有表結點鏈在一起。
注意:
     如果帶權圖,則在表結點中還應增加一個保存權值等相關信息info。

2.鄰接表的表示
     對於無向圖,vi的鄰接表中每個表結點都對應於與vi相關聯的一條邊。因此,將鄰接表的表頭向量稱為頂點表。將無向圖的鄰接表稱為邊表。
注意:
    n個頂點e條邊的無向圖的鄰接表表示中有n個頂點表結點和2e個邊表結點。
     對於有向圖,vi的鄰接表中每個表結點都對應於以vi為始點射出的一條邊。因此,將有向圖的鄰接表稱為出邊表。
注意:
    n個頂點e條邊的有向圖,它的鄰接表表示中有n個頂點表結點和e個邊表結點。

4.有向圖的逆鄰接表
    在有向圖中,為圖中每個頂點vi建立一個入邊表的方法稱逆鄰接表表示法。
    入邊表中的每個表結點均對應一條以vi為終點(即射入vi)的邊。
【例】


注意:
     n個頂點e條邊的有向圖,它的接表表示中有n個頂點表結點和e個邊表結點。

鄰接鏈表表示的圖類 
const int MaxVertices=100;
typedef int VerT;
typedef int DistT;
struct Edge{ int dest; //鄰接頂點下標
                DistT weight; //邊的權值,或更多
                Edge *next; //指針
             };
struct item { VerT data;       //頂點數據
                Edge *adj;     //鄰接邊的指針
             };
item Vertices[MaxVertices];       //頂點的數組 

建立一個無向圖的鄰接鏈表:
void AdjTWGraph::CreatG(int n,int e)
{ int vi,vj; DistT w;
numE=e; numV=n;
cout<<"\n 輸入頂點的信息(整型):" ;
for (int i=1; i<=numV; i++ ) { cout<<"\n "<<i<<": ";
cin>>Vertices[i].data;
}
for ( int i=1; i<=numE; i++ )
{ cout<<"\n 輸入邊的信息(頂點號vi 頂點號vj 邊的權值W):";
cin>>vi>>vj>>w;
//---------------------- 在第vi條鏈表上,鏈入邊(vi,vj)的結點
Edge *q=new Edge;
q->dest=vj; q->weight=w; q->next=NULL; 
//vj是vi的鄰接頂點,w是權值
if(Vertices[vi].adj==NULL) Vertices[vi].adj=q;           //第一次插入
else            //非第一次插入
{ Edge *curr=Vertices[vi].adj, *pre=NULL;
while (curr!=NULL && curr->dest<vj )
{ pre=curr; curr=curr->next; }
if ( pre==NULL )           //在第一個結點前插入
{ q->next=Vertices[vi].adj; Vertices[vi].adj=q; }
else {q->next=pre->next;           //在其他位置插入
pre->next=q;
}
}
//-------------------在第vj條鏈表上,鏈入邊(vj,vi)的結點
Edge *p=new Edge;
p->dest=vi; p->weight=w; p->next=NULL;
if(Vertices[vj].adj==NULL) Vertices[vj].adj=p;           //第一次插入
else            //非第一次插入
{ Edge *curr=Vertices[vj].adj, *pre=NULL;
while (curr!=NULL && curr->dest<vi )
{ pre=curr; curr=curr->next; }
if ( pre==NULL )           //在第一個結點前插入
{ p->next=Vertices[vj].adj; Vertices[vj].adj=p; }
else { p->next=pre->next;           //在其他位置插入
pre->next=p;
}
}
}       //for ( int i=1; i<=numE; i++ )
}            //函數結束
      該算法的時間復雜度是 O(n+2e) ,在上述算法中去掉黑體部分語句,就是有向圖的建立算法,其時間復雜度為 O(n+e) 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM