A. 用鄰接表表示圖進行深度優先遍歷時,通常採用()來實現演算法
使用棧來實現演算法。
用鄰接表表示圖進行深度優先遍歷時,通常採用棧來實現演算法,廣度遍歷使用隊列。
擴展材料:
深度優先遍歷:類似與樹的前序遍歷。從圖中的某個頂點v出發,訪問此頂點,然後從v的未被訪問到的鄰接點進行遍歷,直到圖中所有和v有路徑相通的頂點都被訪問到
註:優先訪問外層節點,訪問到無新頂點時,會進行回退,訪問未被訪問過的分支頂點。
廣度優先遍歷:類似於樹的層序遍歷。從圖中的某個頂點w出發,讓頂點w入隊,然後頂點w再出隊,並讓所有和頂點w相連的頂點入隊,然後再出隊一個頂點t,並讓所有和t相連但未被訪問過的頂點入隊……由此循環,指定圖中所有元素都出隊。
參考資料來源:
知網論文-數據結構中圖的遍歷演算法研究
B. 稀疏圖為什麼用鄰接表存儲而不用鄰接矩陣我知道是空間效率問題,怎麼個說啊謝謝大神!
鄰接表只需存儲非零節點,而矩陣的話是不是要把所有節點的信息都保存上啊,而稀疏圖的非零節點不多啊。所以存儲效率高
C. 關於圖的鄰接表存儲的問題
我用的是VC++,編譯沒錯!!!編譯結果如下圖
D. 無向連通圖的鄰接表的存儲
最近在看這部分,可惜沒記住無向連通圖鄰接表的定義。
你的程序,我看看出了1點問題:
1、typedef struct ArcNode{ //邊(表結點)
int adjvex; //該弧所指向的頂點的位置
struct ArcNode *nextarc; //指向下一條弧的指針
int info; //該弧相關信息的指針
};
缺東西呢,typedef 是要給 struct ArcNode 起個別名,但是你並沒有做。
可改成 typedef struct ArcNode {.....} ArcNode, *pArcNode; 之類的。或者把 typedef 去了
===============================================
void buildhead(ALGraph &G) //創建一個頭結點表
{
int i=65;
while(i < G.vernum+65)
{
G.vertices[i].data = (char)i;
G.vertices[i].firstarc->nextarc=NULL;
i++;
} // 這個過程為什麼要從65 開始呢?不是最大有20個節點嗎?G.vernum的下標應該是 0 - 19 猜對吧?
}
E. 稀疏圖為什麼用鄰接表存儲而不用鄰接矩陣
因為稀疏圖裡面很多0啊,如果用鄰接矩陣每個0都會存儲,而這些0並沒有存儲價值,反而還浪費存儲空間,所以用鄰接表存儲
F. 圖的基本概念,圖的存儲--鄰接矩陣、鄰接表、十字鏈表、鄰接多重表
一個圖(G)定義為一個偶對(V,E),記為G=(V,E)。
V是頂點(Vertex)的非空有限集合,記為V(G)。
E是無序集V&V的一個子集,記為E(G),其元素是圖的弧(Arc)。
將頂點集合為空的圖稱為空圖。
弧:表示兩個頂點v和w之間存在一個關系,用頂點偶對<v,w>表示。
(1)無向圖:
在一個圖中,如果任意兩個頂點構成的偶對(v,w)∈E 是無序的,即頂點之間的連線是沒有方向的,則稱該圖為無向圖。
(2)有向圖:
在一個圖中,如果任意兩個頂點構成的偶對(v,w)∈E 是有序的,即頂點之間的連線是有方向的,則稱該圖為有向圖。一般記作<v,w>
(3)完全無向圖:
在一個無向圖中,如果任意兩頂點都有一條直接邊相連接,則稱該圖為完全無向圖。在一個含有 n 個頂點的完全無向圖中,有n(n-1)/2條邊。
(4)完全有向圖:
在一個有向圖中,如果任意兩頂點之間都有方向互為相反的兩條弧相連接,則稱該圖為完全有向圖。在一個含有 n 個頂點的完全有向圖中,有n(n-1)條邊。
(5)稠密圖、稀疏圖:
若一個圖接近完全圖,稱為稠密圖;稱邊數很少( )的圖為稀疏圖。
(6)頂點的度、入度、出度:
頂點的度(degree)是指依附於某頂點 的邊數,通常記為TD( )。
在無向圖中,所有頂點度的和是圖中邊的2倍。
在有向圖中,要區別頂點的入度(Indegree)與出度(Outdegree)的概念。
頂點 的入度是指以頂點為終點的弧的數目,記為ID ( );
頂點 出度是指以頂點 為始點的弧的數目,記為 OD( )。
頂點 的出度與入度之和稱為 的度,記為TD( )。即TD( )=OD( )+ID ( )。
(7)邊的權、網圖:
與邊有關的數據信息稱為權(weight)。在實際應用中,權值可以有某種含義。
邊上帶權的圖稱為網圖或網路(network)。如果邊是有方向的帶權圖,則就是一個有向網圖。
(8)路徑、路徑長度:
對無向圖,若從頂點 經過若干條邊能到達 ,則稱頂點 和 是連通的,又稱頂點 到 有路徑。
對有向圖,從頂點 到 有有向路徑,指的是從頂點 經過若干條有向邊能到達 。
路徑上邊或有向邊(弧)的數目稱為路徑長度。
(9)簡單路徑、迴路、簡單迴路:
在一條路徑中,若沒有重復相同的頂點,該路徑稱為簡單路徑。
第一個頂點和最後一個頂點相同的路徑稱為迴路(環)。
除第一個頂點與最後一個頂點之外,其他頂點不重復出現的迴路稱為簡單迴路,或者簡單環。
(10)子圖和生成子圖:
對於圖 G=(V,E),G』=(V』,E』),若存在 V』是 V 的子集 ,E』是 E的子集,則稱圖 G』是 G 的一個子圖;
若V』=V且E』是E的子集,則稱圖G』是G的一個生成子圖。
(11)連通圖、連通分量:
對無向圖G=(V,E),若任意 都是連通的,則稱該圖是連通圖,否則稱為非連通圖。
若G是非連通圖,則極大連通子圖稱為連通分量。
極大的含義:指的是對子圖再增加圖G中的其它頂點,子圖就不再連通。
任何連通圖的連通分量只有一個,即本身,而非連通圖有多個連通分量。
(12)強連通圖、強連通分量:
對於有向圖來說,若圖中任意一對頂點 均有從一個頂點 到另一個頂點 有路徑,也有從 到 的路徑,則稱該有向圖是強連通圖。
有向圖的極大強連通子圖稱為強連通分量。
強連通圖只有一個強連通分量,即本身。非強連通圖有多個強連通分量。
(13)生成樹:
一個連通圖(無向圖)的生成樹是一個極小連通子圖,它含有圖中全部n個頂點和只有足以構成一棵樹的n-1條邊,稱為圖的生成樹。
(14)生成森林:
有向樹是只有一個頂點的入度為0,其餘頂點的入度均為1的有向圖。
有向圖的生成森林是這樣一個子圖,由若干棵有向樹組成,含有圖中全部頂點。
(1)鄰接矩陣法(Adjacency Matrix)
基本思想:對於有n個頂點的圖,用一維數組vexs[n]存儲頂點信息,用二維數組A[n][n]存儲頂點之間關系的信息。該二維數組稱為鄰接矩陣。
在鄰接矩陣中,以頂點在vexs數組中的下標代表頂點,鄰接矩陣中的元素A[i][j]存放的是頂點i到頂點j之間關系的信息。
1)無向圖的數組表示
①無向無權圖的鄰接矩陣
無向無權圖其鄰接矩陣是n階對稱方陣。
若兩條邊相連,A[i][j]=1; 若不相連A[i][j]=0。
②無向帶權圖的鄰接矩陣
若兩條邊相連, ,W為權值。
若兩條邊不相連,A[i][j]=
③無向圖鄰接矩陣的特性
無向圖的鄰接矩陣一定是一個對稱矩陣。因此,在具體存放鄰接矩陣時只需存放 上(或下)三角矩陣的元素即可。
對於頂點 ,其度數是第i行的非0元素(或非 元素)的個數。
無向圖的邊數是上(或下)三角形矩陣的非0元素(或非 元素)的個數。
2)有向圖的數組表示
①有向無權圖的鄰接矩陣
若有向無權圖G=(V,E)有n個頂點,則其鄰接矩陣是n階方陣:
若從 到 有弧,A[i][j]=1;
若從 到 沒有弧,A[i][j]=0;
②有向帶權圖的鄰接矩陣
③有向圖鄰接矩陣的特性
對於頂點 ,第i行的非0元素(或非 元素)的個數是其出度OD( );
第i列的非0元素(或非 元素)的個數是其入度ID( );
鄰接矩陣中非0元素(或非 元素)的個數就是圖的弧的個數。
對於n個頂點e條邊的無向圖,鄰接矩陣表示時有n n個元素,2 e個非0元素。
對於n個頂點e條邊的有向圖,鄰接矩陣表示時有n n個元素,e個非0元素。
3)圖的鄰接矩陣的操作
定義兩個數組分別存儲頂點信息(數據元素)和邊或弧的信息(數據元素之間的關系) 。
圖的各種操作。
①圖的創建
②圖的頂點定位
實際上是確定一個頂點在 vexs 數組中的位置(下標) ,其過程完全等同於在順序存儲的線性表中查找一個數據元素。
③向圖中增加頂點
向圖中增加一個頂點的操作,類似在順序存儲的線性表的末尾增加一個數據元素。
④向圖中增加一條弧
根據給定的弧或邊所依附的頂點,修改鄰接矩陣中所對應的數組元素。
(2)鄰接鏈表法
1)基本思想:類似於樹的孩子鏈表法,就是對於圖 G 中的每個頂點 ,將所有鄰接於 的頂點 鏈成一個單鏈表,這個單鏈表就稱為頂點 的鄰接鏈表,再將所有點的鄰接表表頭放到數組中,就構成了圖的鄰接鏈表。
對無向圖,其鄰接鏈表是唯一(按順序鏈接)的;對有向圖,其鄰接鏈表有兩種形式。
2)從圖的鄰接表存儲方法容易看出,這種表示具有以下特點:
①表頭向量中每個分量就是一個單鏈表的頭結點,分量個數就是圖中的頂點數目。
②在邊稀疏的情況下,用鄰接表表示圖比鄰接矩陣節省存儲空間。
③在無向圖的鄰接表中,頂點 的度恰為第 i 個鏈表中的結點數。
④有向圖可以建立一個正鄰接表和逆鄰接表,便於統計每個結點的出度和入度。
⑤在鄰接表上容易找到任一頂點的第一個鄰接點和下一個鄰接點,但要判定任意兩個頂點( 和 )之間是否有邊或弧相連,則需搜索第 i 個或第 j 個鏈表,因此,不及鄰接矩陣方便。
對於n個頂點e條邊的無向圖,鄰接表表示時有n個表頭結點,2 e個表結點。
對於n個頂點e條邊的有向圖,鄰接表表示時有n個表頭結點,表結點數不確定,但正鄰接表加上逆鄰接表表結點數為e。
3)表結點及其類型定義
圖的各種操作
①圖的創建
②頂點定位
圖的頂點定位實際上是確定一個頂點在 AdjList 數組中的某個元素的 data 域內容。
③向圖中增加頂點
向圖中增加一個頂點的操作,在 AdjList 數組的末尾增加一個數據元素。
④向圖中增加一條弧
根據給定弧或邊所依附的頂點,修改單鏈表,無向圖修改兩個單鏈表;有向圖修改一個單鏈表。
(3) 十字鏈表法
十字鏈表(Orthogonal List)是有向圖的另一種鏈式存儲結構,是將有向圖的正鄰接表和逆鄰接表結合起來得到的一種鏈表。
在這種結構中,每條弧的弧頭結點和弧尾結點都存放在鏈表中,並將弧結點分別組織到以弧尾結點為頭(頂點)結點和以弧頭結點為頭(頂點)結點的鏈表中。這種結構的結點邏輯結構如圖所示。
data 域:存儲和頂點相關的信息;
指針域 firstin:指向以該頂點為弧頭的第一條弧所對應的弧結點,即逆鄰接鏈表;
指針域 firstout:指向以該頂點為弧尾的第一條弧所對應的弧結點,即正鄰接鏈表;
尾域 tailvex:指示弧尾頂點在圖中的位置;
頭域 headvex:指示弧頭頂點在圖中的位置;
指針域 hlink:指向弧頭相同的下一條弧;
指針域 tlink:指向弧尾相同的下一條弧;
Info 域:指向該弧的相關信息,比如權值;
結點類型定義:
下圖所示是一個有向圖及其十字鏈表(略去了表結點的 info 域)。實質就是先把圖的正鄰接鏈表(出度)畫出來,然後再把firstin,firstout,hlink,tlink連起來。
(4)鄰接多重表法
鄰接多重表(Adjacency Multilist)是無向圖的另一種鏈式存儲結構。
鄰接多重表的結構和十字鏈表類似,每條邊用一個結點表示。
鄰接多重表中的頂點結點結構與鄰接表中的完全相同,而表結點包括六個域。
data 域:存儲和頂點相關的信息;
指針域 firstedge:指向依附於該頂點的第一條邊所對應的表結點;
標志域 mark:用以標識該條邊是否被訪問過;
ivex 和 jvex 域:分別保存該邊所依附的兩個頂點在圖中的位置;
info 域:保存該邊的相關信息;
指針域 ilink:指向下一條依附於頂點 ivex 的邊;
指針域 jlink:指向下一條依附於頂點 jvex 的邊;
結點類型定義:
鄰接多重表與鄰接表的區別:後者的同一條邊用兩個表結點表示,而前者只用一個表結點表示;除標志域外,鄰接多重表與鄰接表表達的信息是相同的,因此,操作的實現也基本相似。
G. 如何用鄰接表存儲圖結構
我看不太懂這個程序,不過我有些過圖的鄰接表表示,看對你有沒有幫助吧。
#include <iostream>
#include <fstream>
#include <vector>
typedef int QElemTyep;
#include "queue.h"
using namespace std;
typedef int Status;
#define MAX_VERTEX_NUM 30 //圖的最大頂點數
enum BOOL {False,True};
BOOL visited[MAX_VERTEX_NUM]; //全局變數--訪問標志數組
typedef struct ArcNode{
//弧結點
int adjvex; //該弧所指向的頂點的位置
struct ArcNode *nextarc; //指向下一條弧的指針
InfoType *info; //保存邊的信息,可以簡單的改為 int w;
}ArcNode;
typedef struct VNode{
VertexType data;
ArcNode *firstarc;
}VNode,AdjList[MAX_VERTEX_NUM];
class Graph{
public: AdjList vertices; //記錄頂點信息,指向第一條依附該頂點的弧的指針
int vexnum,arcnum; //圖的當前頂點和弧數
int GraphKind; //圖的種類,0---無向圖,1---有向圖
Graph(int vexnum,int arcnum,int kind)
{
this->vexnum=vexnum;
this->arcnum=arcnum;
this->GraphKind=kind;
}
};
void CreateGraph(Graph &G,VertexType *V,ArcType *VR){
//構造鄰接表結構的圖G
int i;
ArcNode *s;
for(i=1;i<=G.vexnum;i++) //初始化指針數組
{
G.vertices[i].data=V[i];
G.vertices[i].firstarc=NULL;
}
for(i=1;i<=G.arcnum;i++)
{
s=(ArcNode *)malloc(sizeof(ArcNode)); //生成一個弧結點
s->nextarc=G.vertices[VR[i].start].firstarc; //插入到鄰接表中
s->adjvex=VR[i].end;
G.vertices[VR[i].start].firstarc=s;
if(G.GraphKind==0) {
//若是無向圖,再插入到終點的弧鏈中
s=(ArcNode *)malloc(sizeof(ArcNode));
s->nextarc=G.vertices[VR[i].end].firstarc;
s->adjvex=VR[i].start;
G.vertices[VR[i].end].firstarc=s;
}
}
}
H. 鄰接表存儲時,空間復雜度O( n+e),還是O(n)
O(n+e),取n次最小權,每次取完會進行n次更新。如果能達到o(n+e),就不需要O(n)。
在有向圖中,描述每個點向別的節點連的邊(點a->點b這種情況)。在無向圖中,描述每個點所有的邊。與鄰接表相對應的存圖方式叫做邊集表,這種方法用一個容器存儲所有的邊。
對於有向圖,vi的鄰接表中每個表結點都對應於以vi為始點射出的一條邊。因此,將有向圖的鄰接表稱為出邊表。
(8)鄰接表的存儲為什麼用數字擴展閱讀:
n個頂點e條邊的有向圖,它的鄰接表表示中有n個頂點表結點和e個邊表結點。(因為有向圖是單向的)
在有向圖中,為圖中每個頂點vi建立一個入邊表的方法稱逆鄰接表表示法。入邊表中的每個表結點均對應一條以vi為終點(即射入vi)的邊。
n個頂點e條邊的有向圖,它的逆鄰接表表示中有n個頂點表結點和e個邊表結點。
I. 數據結構,求無向圖用鄰接矩陣和鄰接表的存儲空間大小,怎麼算
鄰接表所需的存儲空間為e(邊數),但不適合查詢兩點間是否存在路徑
鄰接矩陣所需的存儲空間為你n^2,適合查詢兩點間是否存在路徑
對於第二問,鄰接表所需的存儲空間為9900,鄰接矩陣所需的存儲空間為你n^2=10000,差不多,所以選性能更優的鄰接矩陣
實際上像(2)這種稠密圖(其實是個滿圖)一般適合鄰接矩陣