當前位置:首頁 » 服務存儲 » 圖的鄰接矩陣屬於順序存儲結構
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

圖的鄰接矩陣屬於順序存儲結構

發布時間: 2022-07-27 12:48:48

1. 圖的存儲結構——所存儲的信息有哪些

一、鄰接矩陣存儲方法

鄰接矩陣是表示頂點之間相鄰關系的矩陣。

設G=(V,E)是具有n(n>0)個頂點的圖,頂點的順序依次為0~n-1,則G的鄰接矩陣A是n階方陣,其定義如下:

(1)如果G是無向圖,則:

A[i][j]=1:若(i,j)∈E(G) 0:其他

(2)如果G是有向圖,則:

A[i][j]=1:若<i,j>∈E(G) 0:其他

(3)如果G是帶權無向圖,則:

A[i][j]= wij :若i≠j且(i,j)∈E(G) 0:i=j ∞:其他

(4)如果G是帶權有向圖,則:

A[i][j]= wij :若i≠j且<i,j>∈E(G) 0:i=j∞:其他

注意:帶權圖和不帶權圖表示的元素類型不同。


帶權圖(不論有向還是無向圖)A[i][j]用double表示,不帶權圖(不論有向還是無向圖)A[i][j]用int表示。

用一維數組G[ ]存儲有4個頂點的無向圖如:G[ ] = { 0, 1, 0, 1, 1, 0, 0, 0, 1, 0 }

則頂點2和頂點0之間是有邊的。

如:

鄰接矩陣的特點如下:

(1)圖的鄰接矩陣表示是唯一的。

(2)無向圖的鄰接矩陣一定是一個對稱矩陣。因此,按照壓縮存儲的思想,在具體存放鄰接矩陣時只需存放上(或下)三角形陣的元素即可。

(3)不帶權的有向圖的鄰接矩陣一般來說是一個稀疏矩陣。因此,當圖的頂點較多時,可以採用三元組表的方法存儲鄰接矩陣。

(4)對於無向圖,鄰接矩陣的第i行(或第i列)非零元素(或非∞元素)的個數正好是第i個頂點的度。

(5)對於有向圖,鄰接矩陣的第i行(或第i列)非零元素(或非∞元素)的個數正好是第i個頂點的出度(或入度)。

(6)用鄰接矩陣方法存儲圖,很容易確定圖中任意兩個頂點之間是否有邊相連。但是,要確定圖中有多少條邊,則必須按行、按列對每個元素進行檢測,所花費的時間代價很大。這是用鄰接矩陣存儲圖的局限性。

鄰接矩陣的數據類型定義如下:

#define MAXV <最大頂點個數>

typedef struct

{ int no; //頂點編號

InfoType info; //頂點其他信息

} VertexType; //頂點類型

typedef struct //圖的定義

{ int edges[MAXV][MAXV]; //鄰接矩陣

int n,e; //頂點數,弧數

VertexType vexs[MAXV]; //存放頂點信息

} MGraph; //圖的鄰接矩陣表示類型


二、 鄰接表存儲方法

圖的鄰接表存儲方法是一種順序分配與鏈式分配相結合的存儲方法。

在鄰接表中,對圖中每個頂點建立一個單鏈表,第i個單鏈表中的節點表示依附於頂點i的邊(對有向圖是以頂點i為尾的邊)。每個單鏈表上附設一個表頭節點。

其中,表節點由三個域組成,adjvex指示與頂點i鄰接的點在圖中的位置,nextarc指示下一條邊或弧的節點,info存儲與邊或弧相關的信息,如權值等。

表頭節點由兩個域組成,data存儲頂點i的名稱或其他信息,firstarc指向鏈表中第一個節點。

typedef struct ANode

{ int adjvex; //該邊的終點編號

struct ANode *nextarc; //指向下一條邊的指針

InfoType info; //該邊的相關信息

} ArcNode; //邊表節點類型


typedef struct Vnode

{ Vertex data; //頂點信息

ArcNode *firstarc; //指向第一條邊

} VNode; //鄰接表頭節點類型

typedef VNode AdjList[MAXV]; //AdjList是鄰接表類型

typedef struct

{ AdjList adjlist; //鄰接表

int n,e; //圖中頂點數n和邊數e

} ALGraph; //完整的圖鄰接表類型


鄰接表的特點如下:

(1)鄰接表表示不唯一。這是因為在每個頂點對應的單鏈表中,各邊節點的鏈接次序可以是任意的,取決於建立鄰接表的演算法以及邊的輸入次序。

(2)對於有n個頂點和e條邊的無向圖,其鄰接表有n個頂點節點和2e個邊節點。顯然,在總的邊數小於n(n-1)/2的情況下,鄰接表比鄰接矩陣要節省空間。

(3)對於無向圖,鄰接表的頂點i對應的第i個鏈表的邊節點數目正好是頂點i的度。

(4)對於有向圖,鄰接表的頂點i對應的第i個鏈表的邊節點數目僅僅是頂點i的出度。其入度為鄰接表中所有adjvex域值為i的邊節點數目。

例, 給定一個具有n個節點的無向圖的鄰接矩陣和鄰接表。

(1)設計一個將鄰接矩陣轉換為鄰接表的演算法;

(2)設計一個將鄰接表轉換為鄰接矩陣的演算法;

(3)分析上述兩個演算法的時間復雜度。

解:

(1)在鄰接矩陣上查找值不為0的元素,找到這樣的元素後創建一個表節點並在鄰接表對應的單鏈表中採用前插法插入該節點。

void MatToList(MGraph g,ALGraph *&G)

//將鄰接矩陣g轉換成鄰接表G

{ int i,j,n=g.n; ArcNode *p; //n為頂點數

G=(ALGraph *)malloc(sizeof(ALGraph));

for (i=0;i<n;i++) //給所有頭節點的指針域置初值

G->adjlist[i].firstarc=NULL;

for (i=0;i<n;i++) //檢查鄰接矩陣中每個元素

for (j=n-1;j>=0;j--)

if (g.edges[i][j]!=0)

{ p=(ArcNode *)malloc(sizeof(ArcNode));

//創建節點*p

p->adjvex=j;

p->nextarc=G->adjlist[i].firstarc;

//將*p鏈到鏈表頭

G->adjlist[i].firstarc=p;

}

G->n=n;G->e=g.e;


}


(2)在鄰接表上查找相鄰節點,找到後修改相應鄰接矩陣元素的值。

void ListToMat(ALGraph *G,MGraph &g)

{ int i,j,n=G->n;ArcNode *p;

for (i=0;i<n;i++)

{ p=G->adjlist[i].firstarc;

while (p!=NULL)

{ g.edges[i][p->adjvex]=1;

p=p->nextarc;

}

}

g.n=n;g.e=G->e;

}


(3)演算法1的時間復雜度均為O(n2)。演算法2的時間復雜度為O(n+e),其中e為圖的邊數。

2. 圖的存儲結構是什麼

由於圖的結構比較復雜,任意兩個頂點之間都可能存在關系(邊),無法通過存儲位置表示這種任意的邏輯關系,所以,圖無法採用順序存儲結構。這一點同其他數據結構(如線性表、樹)不同。考慮圖的定義,圖是由頂點和邊組成的,所以,分別考慮如何存儲頂點和邊。圖常用的存儲結構有鄰接矩陣、鄰接表、十字鏈表和鄰接多重表。

3. 數據結構:畫出下圖的鄰接矩陣存儲結構

我定義一個int型二維數組 G[5][5].
點a,b,c,d分別定義編號為1,2,3,4

G[u][v]的值為零 則有向邊(u,v)不聯通
若值為1則有向邊(u,v)聯通
又因為在c,c ,java中 數組的范圍是從0開始的
為了使用方便 我們不使用下標為0的數組元素
因為有四個點 所以我們定義一個5x5的二維數組
矩陣數據如下
00000
00110
00000
00001
01000
其中 G[1][2] G[1][3]G[3][4]G[4][1]的值為一

4. 鄰接矩陣的表示法

在圖的鄰接矩陣表示法中:
① 用鄰接矩陣表示頂點間的相鄰關系
② 用一個順序表來存儲頂點信息
圖的矩陣
設G=(V,E)是具有n個頂點的圖,則G的鄰接矩陣是具有如下性質的n階方陣:

【例】
下圖中無向圖G 5 和有向圖G 6 的鄰接矩陣分別為A l 和A 2 。

網路矩陣
若G是網路,則鄰接矩陣可定義為:
其中:
w ij 表示邊上的權值;
∞表示一個計算機允許的、大於所有邊上權值的數。
【例】下面帶權圖的兩種鄰接矩陣分別為A 3 和A 4 。

圖的鄰接矩陣存儲結構形式說明
#define MaxVertexNum l00 //最大頂點數,應由用戶定義
typedef char VertexType; //頂點類型應由用戶定義
typedef int EdgeType; //邊上的權值類型應由用戶定義
typedef struct{
VextexType vexs[MaxVertexNum] //頂點表
EdeType edges[MaxVertexNum][MaxVertexNum];//鄰接矩陣,可看作邊表
int n,e; //圖中當前的頂點數和邊數
}MGragh;
注意:
① 在簡單應用中,可直接用二維數組作為圖的鄰接矩陣(頂點表及頂點數等均可省略)。
② 當鄰接矩陣中的元素僅表示相應的邊是否存在時,EdgeTyPe可定義為值為0和1的枚舉類型。
③無向圖的鄰接矩陣是對稱矩陣,對規模特大的鄰接矩陣可壓縮存儲。
④鄰接矩陣表示法的空間復雜度S(n)=0(n 2 )。
⑤建立無向網路的演算法。
void CreateMGraph(MGraph *G)
{//建立無向網的鄰接矩陣表示
int i,j,k,w;
scanf("%d%d",&G->n,&G->e); //輸入頂點數和邊數
for(i = 0;i < n;i++) //讀入頂點信息,建立頂點表
{
G->vexs=getchar();
}
for(i = 0;i < G->n;i++)
{
for(j = 0;j <G->n;j++)
{
G->edges[i][j] = 0; //鄰接矩陣初始化
}
}
for(k = 0;k < G->e;k++)
{//讀入e條邊,建立鄰接矩陣
scanf("%d%d%d",&i,&j,&w); //輸入邊(v i ,v j )上的權w
G->edges[i][j]=w;
G->edges[j][i]=w;
}
}//CreateMGraph
該演算法的執行時間是0(n+n 2 +e)。由於e
根據圖的定義可知,圖的邏輯結構分為兩部分:V和E的集合。因此,用一個一維數組存放圖中所有頂點數據;用一個二維數組存放頂點間關系(邊或弧)的數據,稱這個二維數組為鄰接矩陣。鄰接矩陣又分為有向圖鄰接矩陣和無向圖鄰接矩陣。
Matlab表達N=4;//圖中的節點數目
dag=zeros(N,N);//鄰接矩陣初始化,值均為0
C=1;S=2;R=3;
W=4;//制定各節點編號
dag(C,[RS])=1;//有兩條有向邊:C->R,C->S
dag(R,W)=1;//有向邊:R->W
dag(S,W)=1;//有向邊:S->W

5. 線性的數據結構可以順序存儲也可以鏈接存儲

三、 判斷題(每小題1分,共10分,錯誤打×,正確打√)
1、線性的數據結構可以順序存儲,也可以鏈接存儲.非線性的數據結構只能鏈接存儲.( )
2、單鏈表從任何一個結點出發,都能訪問到所有結點.( )
3、在只有度為0和度為k的k叉樹中,設度為0的結點有n0個,度為k的結點有nk個,則有n0=nk+1 ( )
4、將一棵樹轉換成二叉樹後,根結點沒有左子樹( )
5、鄰接表表示無向圖,鄰接表中的結點個數是無向圖中邊數的2倍.( )
6、 用鄰接矩陣表示圖所用的存儲空間大小與圖的邊數成正比.( )
7、負載因子(裝填因子)是散列表的一個重要參數,它反映散列表的裝滿程度.( )
8、赫夫曼樹一定是滿二叉樹.( )
9、高度為h的k叉樹至多有kh-1個結點.( )
10、對任意一個圖,從它的某個頂點出發進行一次深度優先或廣度優先搜索遍歷可訪問到該圖的每個頂點.( )
2、鍵碼序列(26,25,20,33,21,24,42,37),要用散列法進行存儲,規定負載因子α=0.5.
1)\x05(2分)請給出除余法的散列函數.
2)\x05(3分)用鏈接法解決碰撞,請畫出插入所有的關鍵碼後得到的散列表.
3、(6分)已知序列[10,18,4,3,6,12,l,9,15,8],請給出採用希爾排序法(d1=5、2、1)對該序列做升序排序時的每一趟的結果.
.
7、(6分)下圖表示一個地區的通訊網,邊表示城市間的通訊線路,邊上的權表示架設線路花費的代價,選擇能溝通每個城市且總代價最省的n-1條線路,畫出選擇的過程和最終結果.

6. 鄰接表的簡介

圖的鄰接矩陣存儲方法跟樹的孩子鏈表示法相類似,是一種順序分配和鏈式分配相結合的存儲結構。如這個表頭結點所對應的頂點存在相鄰頂點,則把相鄰頂點依次存放於表頭結點所指向的單向鏈表中。如詞條概念圖所示,表結點存放的是鄰接頂點在數組中的索引。對於無向圖來說,使用鄰接表進行存儲也會出現數據冗餘,表頭結點A所指鏈表中存在一個指向C的表結點的同時,表頭結點C所指鏈表也會存在一個指向A的表結點。
鄰接表是圖的一種最主要存儲結構,用來描述圖上的每一個點。對圖的每個頂點建立一個容器(n個頂點建立n個容器),第i個容器中的結點包含頂點Vi的所有鄰接頂點。實際上我們常用的鄰接矩陣就是一種未離散化每個點的邊集的鄰接表。
在有向圖中,描述每個點向別的節點連的邊(點a->點b這種情況)。
在無向圖中,描述每個點所有的邊(點a-點b這種情況)
與鄰接表相對應的存圖方式叫做邊集表,這種方法用一個容器存儲所有的邊。
工業上有很多非常好的圖庫的實現,例如C++的boost graph庫.如果可以,盡量用這些庫,這樣可以大大提高你的效率。

7. 圖的鄰接矩陣和鄰接表的存儲結構各有什麼特點

圖的鄰接表數據類型描述如下:
const int N=maxn; // maxn表示圖中最大頂點數
const int E=maxe ; // maxe圖中最大邊數
struct Edge{
int u,v; //邊所鄰接的兩個頂點
int w; //邊的權值
int next; //邊指針,指向下一條邊的內存池地址
}edge[E]; // 靜態內存池,用於分配邊
int head[N]; // 表頭
int num; // 內存池的指針

8. 圖的存儲結構有哪些

最常見的:
順序查找:適合順序結構和鏈式結構
二分查找:適合順序結構

其他的二叉查找樹、B-樹之類有自己的數據結構

9. 圖的存儲結構

鄰接矩陣:
有向圖的鄰接矩陣
具有n個頂點的有向圖可以用一個n′n的方形矩陣表示。假設該矩陣的名稱為M,則當<vi,vj>是該有向圖中的一條弧時,M[i,j]=1;否則M[i,j]=0。第i個頂點的出度為矩陣中第i行中"1"的個數;入度為第i列中"1"的個數,並且有向圖弧的條數等於矩陣中"1"的個數。
無向圖的鄰接矩陣
具有n個頂點的無向圖也可以用一個n′n的方形矩陣表示。假設該矩陣的名稱為M,則當(vi,vj)是該無向圖中的一條邊時,M[i,j]=M[j,i]=1;否則,M[i,j]=M[j,j]=0。第i個頂點的度為矩陣中第i 行中"1"的個數或第i列中"1"的個數。圖中邊的數目等於矩陣中"1"的個數的一半,這是因為每條邊在矩陣中描述了兩次。
在C 語言中,實現鄰接矩陣表示法的類型定義如下所示: #defineMAX_VERTEX_NUM20typedefstructgraph{Elemtypeelem[MAX_VERTEX_NUM][MAX_VERTEX_NUM];intn;}Graph;鄰接表
邊結點的結構為:
adjvex是該邊或弧依附的頂點在數組中的下標,next是指向下一條邊或弧結點的指針
elem是頂點內容,firstedge是指向第一條邊或弧結點的指針。
在C語言中,實現鄰接表表示法的類型定義如下所示: #defineMAX_VERTEX_NUM30//最大頂點個數typestructEdgeLinklist{//邊結點intadjvex;structEdgeLinklist*next;}EdgeLinklist;typedefstructVexLinklist{//頂點結點Elemtypeelem;EdgeLinklist*firstedge;}VexLinklist,AdjList[MAX_VERTEX_NUM];創建有向圖和無向圖鄰接表的演算法實現:
(1) 創建有向圖鄰接表 voidCreate_adj(AdjListadj,intn){for(i=0;i<n;i++){//初始化頂點數組scanf(&adj.elem);adj.firstedge=NULL;}scanf(&i,&j);//輸入弧while(i){s=(EdgeLinklist*)malloc(sizeof(EdgeLinklist));//創建新的弧結點s->adgvex=j-1;s->next=adj[i-1].firstedge;//將新的弧結點插入到相應的位置adj[i-1].firstegde=s;scanf(&i,&j);//輸入下一條弧}}(2)創建無向圖的鄰接表 voidCreate_adj(AdjListadj,intn){for(i=0;i<n;i++){//初始化鄰接表scanf(&adj.elem);adj.firstedge=NULL;}scanf(&i,&j);//輸入邊while(i){s1=(EdgeLinklist*)malloc(sizeof(EdgeLinklist));s1->adgvex=j-1;s2=(EdgeLinklist*)malloc(sizeof(EdgeLinklist));s2->adgvex=i-1;s1->next=adj[i-1].firstedge;adj[i-1].firstegde=s1;s2->next=adj[j-1].firstedge;adj[j-1].firstegde=s2;scanf(&i,&j);}}

10. 圖的鄰接矩陣

為對稱矩陣。根據矩陣性質可知原因:鄰接矩陣(AdjacencyMatrix):是表示頂點之間相鄰關系的矩陣。設G=(V,E)是一個圖,其中V={v1,v2,…,vn}。G的鄰接矩陣是一個具有下列性質的n階方陣:對無向圖而言,鄰接矩陣一定是對稱的,而且對角線一定為零。無向圖的鄰接矩陣一定是對稱的,而有向圖的鄰接矩陣不一定對稱。因此,用鄰接矩陣來表示一個具有n個頂點的有向圖時需要n^2個單元來存儲鄰接矩陣;對有n個頂點的無向圖則只存入上(下)三角陣中剔除了左上右下對角線上的0元素後剩餘的元素,故只需1+2++(n-1)=n(n-1)/2個單元。無向圖鄰接矩陣的第i行(或第i列)非零元素的個數正好是第i個頂點的度。