考研數據結構--圖

                                         **圖**

新的一週,最近感覺時間過得好快啊!!!
爭取在開學前整理完!!!開學後二刷王道!!!
(加油!!!!!)
直接上圖吧!
在這裏插入圖片描述
開始正題!!
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;//拓撲排序成功 
 } 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章