**圖**
新的一週,最近感覺時間過得好快啊!!!
爭取在開學前整理完!!!開學後二刷王道!!!
(加油!!!!!)
直接上圖吧!
開始正題!!
1.圖的存儲
//圖的鄰接矩陣
#define MaxVertexNum 100 //頂點數目的最大值
typedef char VertexType;//頂點的數據類型
typedef int EdgeType;//帶權圖中邊上權值的數據類型
typedef struct{
VertexType Vex[MaxVertexNum];//頂點表
EdgeType Edge[MaxVerteNum][MaxVerteNum];//鄰接矩陣,邊表
int vexnum,arcnum;//圖的當前頂點數和邊數
}MGraph;
//圖的鄰接表存儲
#define MaxVertexNum 100 //圖中頂點數目的最大值
typedef struct ArcNode{ //邊表結點
int adjvex;//該邊所指向的頂點的位置
struct ArcNode *next; //指向下一條邊的指針
}ArcNode;
typedef struct VNode{ //頂點表結點
VertexType data;//頂點信息
ArcNode *first;//指向第一依附該頂點的邊的指針
}VNode,AdjList[MaxVertexNum];
typedef struct{
AdjList vertices;//鄰接表
int vexnum,arcnum;//圖的頂點數和邊數
}ALGraph; //ALGraph是以鄰接表存儲的圖類型
2.十字鏈表的結構定義
//圖的十字鏈表結構定義
#define MaxVertexNum 100
typedef struct ArcNode{ //邊表結點
int tailvex,headvex;//該邊的頭尾結點
struct ArcNode *hlink,*tlink;//分別指向邊頭相同和邊尾相同的結點
}ArcNode;
typedef struct VNode{//頂點表結點
VertexType data;//頂點信息
ArcNode *firstin,*firstout;//珍惜第一條入邊和出邊
}VNode;
typedef struct{
VNode xlist[MaxVertexNum];//鄰接表
int vexnum,arcnum;//圖的頂點數和邊數
}GLGraph;//GLGraph是以十字鄰接存儲的圖類型
3.圖的鄰接多重表存儲結構定義
//圖的鄰接多重表存儲結構定義
#define MaxVertexNum 100
typedef struct ArcNode{//邊表結點
bool mark;//訪問標記
int ivex,jvex;//分別指向該邊的兩個結點
struct ArcNode *ilink,*jlink;//分別指向兩個頂點的下一條邊
}ArcNode;
typedef struct VNode{ //頂點表結點
VertexType data;//頂點信息
ArcNode *firstedge;//指向第一條依附該頂點的邊
}VNode;
typedef struct{
VNode adjmulist[MaxVertexNum];//鄰接表
int vexnum,arcnum;//圖的頂點數和邊數
}AMLGraph;//AMLGraph是以鄰接多重表存儲的圖類型
4.廣度優先算法的僞代碼
//廣度優先搜索算法的僞代碼
bool visited[MAX_VERTEX_NUM];//訪問標記數組
void BFSTraverse(Graph G){
//對圖G進行廣度優先遍歷,設訪問函數爲visit()
for(int i=0;i<G.vexnum;i++)
visited[i]=FALSE;//訪問標記數組初始化
InitQueue(Q);//初始化輔助隊列Q
for(i=0;i<G.vexnum;i++) //從0號頂點開始遍歷
if(!visited[i])//對每個連通分量調用一次BFS
BFS(G,i);//vi未被訪問過,從vi開始BFS
}
void BFS(Graph G,int v){
//從頂點v出發,廣度優先遍歷圖G,算法藉助一個輔助隊列Q
visit(v);//訪問初始頂點v
visited[v]=TRUE;//對v做已訪問標記
Enqueue(Q,v);//頂點v入隊列
while(!isEmpty(Q)) {
Dequeue(Q,v);//頂點v出隊列
for(w=FirstNeighbor(G,v);w>=0;w=NextNeighbor(G,v,w)) //檢測v所有鄰接點
//FirstNeighbor(G,v)求圖G中頂點v的第一個鄰接點,若有則返回頂點號。若u沒有鄰接點或圖中不存在v,則返回-1
if(!visited[w]) {
//w爲v的尚未訪問的鄰接頂點
visited[w]=TRUE;//對w做已訪問標記
EnQueue(Q,w);//頂點w入隊列
}
}
}
BFS算法求解單源最短路徑問題
//BFS算法求解單源最短路徑問題
void BFS_MIN_Distance(Graph G,int u)
{
//d[i]表示從u到i結點的最短路徑
for(i=0;i<G.vexnum;++i)
d[i]= ∞;//初始化路徑長度
visited[u]=TRUE;d[u]=0;
EnQueue(Q,u);
while(!isEmpty(Q)) {
//BFS算法主要過程
DeQueue(Q,u);//隊頭元素u出隊
for(w=FirstNeighbor(G,u);w>=0;w=NextNeighbor(G,u,w))
//FirstNeighbor(G,u)求圖G中頂點u的第一個鄰接點,若有則返回頂點號。若u沒有鄰接點或圖中不存在u,則返回-1
//NextNeighbor(G,u,w)假設圖G中頂點w是頂點u的一個鄰接點,返回除w之外頂點u的下一個鄰接點的頂點號,
//若w是u的最後一個鄰接點,則返回-1
if(!visited[w]){
//w爲u的尚未訪問的鄰接頂點
visited[w]=TRUE;//設已訪問標記
d[w]=d[u]+1;//路徑長度+1
EnQueue(Q,w);//頂點w入隊
}
}
}
5.遞歸形式 深度優先算法
//遞歸形式 深度優先算法
bool visited[MAX_VERTEX_NUM];//訪問標記數組
void DFSTraverse(Graph G){
//對圖G進行深度優先遍歷,訪問函數爲visit()
for(v=0;v<G.vexnum;++v)
visited[v]=FALSE;//初始化已訪問標記數組
for(v=0;v<G.vexnum;++v)
if(!visited[v])
DFS(G,v);
}
void DFS(Graph G,int v)
{
//從頂點v出發,採用遞歸思想,深度優先遍歷圖G
visit(v);//訪問頂點v
visited[v]=TRUE;//設已訪問標記
for(w=FirstNeighbor(G,v);w>=0;w=NextNeighbor(G,v.w))
if(!visited[w]){ //w爲u的尚未訪問的鄰接頂點
DFS(G,w);
}
}
6.弗洛伊德算法(天勤)
//弗洛伊德算法(天勤)
void Floyd(MGraph g,int Path[][maxSize])
{
int i,j,k;
int A[maxSize][maxSize];
//雙循環對數組A[][]和Path[][]進行了初始化
for(i=0;i<g.n;i++)
{
A[i][j]=g.edges[i][j];
Path[i][j]=-1;
}
//下面三層循環是本算法主要操作,完成了以k爲空間點對所有的頂點對{i,j}進行行檢測和修改
for(k=0;k<g.n;++k)
for(j=0;j<g.n;++j)
if(A[i][j]>A[i][k]+A[k][j])
{
A[i][j]>A[i][k]+A[k][j];
Path[i][j]=k;
}
}
7.拓撲排序
//拓撲排序
bool TopologicalSort(Graph G)
{
//若G存在拓撲序列,返回true,否則返回false,這時G中存在環
InitStack(S);//初始化棧,存儲入度爲0的頂點
for(int i=0;i<G.vexnum;i++)
if(indegree[i]==0)
Push(S,i);//將所有入度爲0的頂點進棧
int count=0;//計數,記錄當前已經輸出的頂點數
while(!IsEmpty(S)) {
///棧不空,則存在入度爲0的頂點
Pop(S,i);//棧頂元素出棧
print[count++]=i;//輸出頂點i
for(p=G.vertices[i].firstarc;p->nextarc){
//將所有i指向的頂點的入度減一,並且將入度減爲0的頂點壓入棧S
v=p->adjvex;
if(!(--indegree[v]))
Push(S,v);//入度爲0,則入棧
}
}
if(count<G.vexnum)
return false;//排序失敗,有向圖中有迴路
else
return true;//拓撲排序成功
}