實驗六 圖的遍歷
一、實驗目的
1.掌握圖的相關概念。
2.掌握用鄰接矩陣和鄰接表的方法描述圖的儲存結構。
3.掌握圖的深度優先搜尋和廣度優先搜尋遍歷的方法及其計算機的實現。
4.理解最小生成樹的有關演算法
二、實驗內容
1.用鄰接表作為圖的儲存結構建立一個圖,並對此圖分別進行深度優先搜尋和廣度優先搜尋遍歷。
2.用鄰接矩陣作為圖的儲存結構建立一個網,並構造該網的最小生成樹(選做)。
三、實驗要求
1、用鄰接表作為圖的儲存結構建立一個圖,並對此圖分別進行深度優先搜尋和廣度優先搜尋遍歷。
(1)輸入無向圖的頂點數、邊數及各條邊的頂點對,建立用鄰接表表示的無向圖。
(2)對圖進行深度優先搜尋和廣度優先搜尋遍歷,並分別輸出其遍歷序列。
2、用鄰接矩陣作為圖的儲存結構建立一個網,構造該網的最小生成樹。
(1)輸入無向圖的頂點數、邊數及各條邊的頂點序號對和邊上的權值,建立用鄰接矩陣表示的無向網。
(2)用Prim演算法構造該無向網的最小生成樹。
(3)在實現普里姆演算法時,採用鄰接矩陣cost表示給定的無向網,矩陣元素定義為:
四、詳細程式清單
//1.鄰接表、DFS和BFS #include <stdio.h> #include <stdlib.h> #define MAX_VERTEX_NUM 30 typedef struct arcnode//邊表結點 { int adjvex;//鄰接點域,儲存該頂點對應的下標 struct arcnode *nextarc;//鏈域,指向下一個鄰接點 } arcnode,*Linkarc; typedef struct//頂點表節點 { arcnode *firstarc;//邊表頭指標 int tag;//0代表未被訪問,1代表已被訪問 }vexnode; typedef struct//頂點陣列 { vexnode adjlist[MAX_VERTEX_NUM]; int vexnum,arcnum;//圖中當前頂點數和邊數 }Algraph; typedef struct{//順序佇列 int *base; int front; int rear; }Sqqueue; Sqqueue Q; void Initqueue(Sqqueue&Q)//初始化佇列 { Q.base=(int*)malloc(sizeof(int)); Q.front=Q.rear=0; } void Enqueue(Sqqueue &Q, int e)//入佇列 { Q.base[Q.rear]=e; Q.rear=Q.rear+1; } int Dequeue(Sqqueue &Q)//出佇列 { int e; e=Q.base[Q.front]; Q.front=Q.front+1; return e; } void CreateUDG(Algraph*G)//建立無向圖的鄰接表 { int i,j,k,w,v,s,d; Linkarc p,q; printf("輸入頂點數:"); scanf("%d",&G->vexnum); printf("輸入邊數:"); scanf("%d",&G->arcnum); for (i=1;i<=G->vexnum;i++)//頂點表 { G->adjlist[i].tag=0;//初始化為0 G->adjlist[i].firstarc=NULL; } for (k=1;k<=G->arcnum;k++)//頂點所包含的連結串列 { printf("輸入邊%d的一對頂點:",k); scanf("%d%d",&s,&d); p=(arcnode*)malloc(sizeof(arcnode)); q=(arcnode*)malloc(sizeof(arcnode)); p->adjvex=d; q->adjvex=s; p->nextarc=G->adjlist[s].firstarc;G->adjlist[s].firstarc=p; q->nextarc=G->adjlist[d].firstarc;G->adjlist[d].firstarc=q; } } void Dfs(Algraph*G,int v) //深度優先遍歷 { int w; arcnode *p; printf("%5d",v); G->adjlist[v].tag=1; p=G->adjlist[v].firstarc; while(p!=NULL) { w=p->adjvex; if(G->adjlist[w].tag==0) Dfs(G,w); p=p->nextarc; } } void Bfs(Algraph*G,int v) //廣度優先遍歷 { int v1,w; arcnode *p; Q.base=NULL; Initqueue(Q); printf("%5d",v); G->adjlist[v].tag=1; Enqueue(Q,v); while(Q.front!=Q.rear) { v1=Dequeue(Q); p=G->adjlist[v1].firstarc; while(p!=NULL) { w=p->adjvex; if(G->adjlist[w].tag==0) { printf("%5d",w); G->adjlist[w].tag=1; Enqueue(Q,w); } p=p->nextarc; } } } int main() { int v=1;//題目沒有規定,預設從1結點開始遍歷 Algraph*G=(Algraph*)malloc(sizeof(Algraph)); CreateUDG(G); printf("深度優先遍歷為:"); Dfs(G,v); for (int i=1;i<=G->vexnum;i++) G->adjlist[i].tag=0;//將全部tag重新賦0 printf("\n廣度優先遍歷為:"); Bfs(G,v); return 0; }
//2.鄰接矩陣和prim #include<stdio.h> #include<stdlib.h> #define INFINITY 0x7FFFFFFF //定義最大值∞ #define MAX_VEX_NUM 50 #define MAX_VERTEX_NUM 2500 typedef struct { int vexs[MAX_VERTEX_NUM];//頂點名 int cost[MAX_VEX_NUM][MAX_VEX_NUM];//各邊權值 int vexnum,arcnum; }Mgraph; Mgraph G; typedef struct ///輔助陣列 { int lowcost; //權值 int closest; //點序號 }Closedge; Closedge closedge[MAX_VEX_NUM]; int LocateVex(Mgraph &G,int x) { for(int i=1;i<=G.vexnum;i++) { if(x==G.vexs[i]) return i; } } void CreateUDN(Mgraph &G) //在鄰接矩陣儲存結構上,構造無向網G { int i,j,k,w; int v1,v2; printf("輸入頂點數和邊數:"); scanf("%d%d",&G.vexnum,&G.arcnum);//讀入頂點和邊數目 printf("輸入各頂點名\n"); for(i=1;i<=G.vexnum;i++)//頂點名 { printf("點%d:",i); scanf("%d",&G.vexs[i]); } for(i=1;i<=G.vexnum;i++) //鄰接矩陣初始化 for(j=1;j<=G.vexnum;j++) { if(i==j) G.cost[i][j]=0; else G.cost[i][j]=INFINITY; } printf("輸入各頂點對和權值\n"); for(k=1;k<=G.arcnum;k++)//構造鄰接矩陣 { scanf("%d%d%d",&v1,&v2,&w); i=LocateVex(G,v1); j=LocateVex(G,v2);//確定v1、v2在圖中的位置 G.cost[i][j]=w; G.cost[j][i]=G.cost[i][j]; } } void Prim(Mgraph G,int v) { int i,j,k,min,x,y; int sum=0;//總權值 x=LocateVex(G,v); for(i=1;i<=G.vexnum;i++)//初始化陣列closedge { if(i!=x) { closedge[i].lowcost=G.cost[x][i]; closedge[i].closest=G.vexs[x]; } } closedge[x].lowcost=0; //初始U={v} for(i=1;i<G.vexnum;i++) { min=INFINITY; for(j=1;j<=G.vexnum;j++) if(closedge[j].lowcost!=0&&closedge[j].lowcost<min) { min=closedge[j].lowcost; k=j; } printf("%d-%d:%d\n",closedge[k].closest,k,min); //輸出最小邊 sum+=min; closedge[k].lowcost=0; for(j=1;j<=G.vexnum;j++) if (closedge[j].lowcost!=0&&G.cost[k][j]<closedge[j].lowcost) { closedge[j].lowcost=G.cost[k][j]; closedge[j].closest=k; } } printf("總權值為%d\n",sum); } int main() { int v=1;//題目沒有規定,預設從A結點開始遍歷 CreateUDN(G); printf("最小生成樹為:\n"); Prim(G,v); }
五、程式執行結果
1. 鄰接表、DFS和BFS
//其實遍歷結果有很多種,不一定是這個,我湊巧和書上一樣了。。。
2. 鄰接矩陣和prim
六、實驗心得體會
1. 在儲存稀疏圖的時候,用鄰接表比鄰接矩陣更省空間。
2. 在鄰接表上容易找到任一頂點的第一個鄰接點和下一個鄰接點,但要判斷任一兩個點之間是否相連,則需搜尋第i或第j個連結串列,此時用鄰接矩陣更方便。
3. DFS和BFS的遍歷結果不一定唯一。
4. C語言是沒有無窮大的,因此,一般用一個很大的數來近似替代無窮大:#define INFINITY 0x7FFFFFFF。
5. Prim演算法的時間複雜度為O(n²),與網的邊數無關,於是適合於稠密圖;而Kruskal演算法的時間主要取決於邊數,於是更適合於稀疏圖。
相關推薦
實驗六 圖的遍歷
一、實驗目的 1.掌握圖的相關概念。 2.掌握用鄰接矩陣和鄰接表的方法描述圖的儲存結構。 3.掌握圖的深度優先搜尋和廣度優先搜尋遍歷的方法及其計算機的實現。 4.理解最小生成樹的有關演算法 二、實驗內容 1.用鄰接表作為圖的儲存結構建立一個圖,並對此圖分別進行深度優先搜尋
算法學習筆記(六) 二叉樹和圖遍歷—深搜 DFS 與廣搜 BFS
創建 mark preorder 第一個 高度 變量初始化 term link 文章 圖的深搜與廣搜 復習下二叉樹、圖的深搜與廣搜。從圖的遍歷說起。圖的遍歷方法有兩種:深度優先遍歷(Depth First Search),
leetcode 847. Shortest Path Visiting All Nodes 無向連通圖遍歷最短路徑
sel shu turn 判斷 lam 最短 額外 動態 訪問 設計最短路徑 用bfs 天然帶最短路徑 每一個狀態是 當前的階段 和已經訪問過的節點 下面是正確但是超時的代碼 class Solution: def shortestPathLength(self,
第十二週專案3 - 圖遍歷演算法實現(2)
/*Copyright (c) 2015, 煙臺大學計算機與控制工程學院 * All rights reserved. * 檔名稱:H1.cpp * 作者:辛志勐 * 完成日期:2015年11月23日 * 版本號:VC6.0 * 問題描述:廣度優先遍歷——BFS * 輸入描述:無 * 程式輸出:圖的
第十二週專案3 - 圖遍歷演算法實現(1)
/*Copyright (c) 2015, 煙臺大學計算機與控制工程學院 * All rights reserved. * 檔名稱:H1.cpp * 作者:辛志勐 * 完成日期:2015年11月23日 * 版本號:VC6.0 * 問題描述:實現圖遍歷演算法,輸出圖結構的深度優先(DFS)遍歷序列
信管117118李志榮資料結構實驗六---圖的實驗
#include<iostream> #include<string> using namespace std; template<typename T> class Graph { private: enum { zero = 0, Max = 5 }; i
實驗六 圖的實驗1
#include<iostream.h> const int Maxsize=6; const int Maxedge=6; int visited[Maxsize]={0}; struct ArcNode { int adjvex; ArcNode*nextarc; }
DS圖遍歷--廣度優先搜尋
給出一個圖的鄰接矩陣,對圖進行深度優先搜尋,從頂點0開始 注意:圖n個頂點編號從0到n-1 輸入 第一行輸入t,表示有t個測試例項 第二行輸入n,表示第1個圖有n個結點 第三行起,每行輸入鄰接矩陣的一行,以此類推輸入n行 第i個結點與其他結點如果相連則為1,無
python 圖 遍歷-深度優先和廣度優先 II
在上一篇(python 圖 遍歷-深度優先和廣度優先)的程式碼上加了最小生成樹和拓撲序列功能。程式碼如下: #!/usr/bin/env python #-*- coding:utf8 -*- import copy class Graph(object):
第六章 遍歷二叉樹及推導遍歷結果(前序、中序和後續)
二叉樹遍歷方法 下面幾種演算法是利用遞迴的方法實現的 - 前序遍歷:先列印輸出,再先序遍歷左子樹,最後先序遍歷右子樹 - 中序遍歷:中序遍歷左子樹,再列印,最後中序遍歷右子樹 - 後序遍歷:先後序遍歷左子樹,再後序遍歷右子樹,最後列印輸出 - 總結:前
無向圖遍歷(廣度、深度)
昨天偷懶,今天發無向圖的遍歷。明天英語並不是很慌,雖然沒怎麼複習= =,可能這就是廢柴大學生的淡定吧。 1 #include<stdio.h> 2 #include<stdlib.h> 3 #define Max 20 4 bool visited[Max];
樹的操作集合(包括樹的建立,六種遍歷方法等)
由於樹的操作離不開指標,所以樹建立和遍歷比線性表複雜很多,文字用C++實現了樹的建立和建立完之後的六種遍歷方法,現在已知某個八個結點的二叉樹的前序遍歷序列是:1,2,4,7,3,5,6,8;中序遍歷序列是:4,7,2,1,5,3,8,6;根據前中後續的遍歷規則,可以得
圖遍歷(深度搜索與廣度搜索和生成樹邊集)
}void DFS(AMLGraph G,int v);void DFSTraverse(AMLGraph G ,char start){int v,z;for(v=0;v<G.vexnum;v++)Visited[v]=0; z=LocateVex(G,start);for(v=0;v<G
【圖】實驗題二:實現圖的遍歷算法
malloc for clu %d type font AS arc -- 遞歸深度優先遍歷算法 1 #include<stdio.h> 2 #include<malloc.h> 3 #define MAXV 100 4 #def
《資料結構與演算法》第六次 圖及圖的遍歷(上)
《資料結構與演算法那》第六次課實驗內容 圖及圖的遍歷(上) 實驗目的: 熟悉圖的兩種儲存結構:鄰接矩陣和鄰接連結串列。 掌握在圖的鄰接表儲存結構上的遍歷演算法的實現。 實驗內容: 開發c++類adjacencyGraph,用鄰接矩陣描述一個無向圖,要求可
資料結構實驗之圖論二:圖的深度遍歷(SDUT 2107)(簡單DFS)
題解:圖的深度遍歷就是順著一個最初的結點開始,把與它相鄰的結點都找到,也就是一直往下搜尋直到盡頭,然後在順次找其他的結點。 #include <bits/stdc++.h> using namespace std; int gra[200][200]; //儲存圖的大小 int
資料結構實驗之圖論二:圖的深度遍歷__DFS
Problem Description 請定一個無向圖,頂點編號從0到n-1,用深度優先搜尋(DFS),遍歷並輸出。遍歷時,先遍歷節點編號小的。 Input 輸入第一行為整數n(0 < n < 100),表示資料的組數。 對於每組資料,第一行是兩個整數k,m(0 < k
資料結構實驗之圖論一:基於鄰接矩陣的廣度優先搜尋遍歷__BFS
Problem Description 給定一個無向連通圖,頂點編號從0到n-1,用廣度優先搜尋(BFS)遍歷,輸出從某個頂點出發的遍歷序列。(同一個結點的同層鄰接點,節點編號小的優先遍歷) Input 輸入第一行為整數n(0< n <100),表示資料的組數。 對於每組
《資料結構與演算法設計》實驗報告書之圖的遍歷操作
《資料結構與演算法設計》實驗報告書之圖的遍歷操作 實驗專案 圖的遍歷操作 實驗目的 掌握有向圖和無向圖的概念;掌握鄰接矩陣和鄰接連結串列建立圖的儲存結構;掌握DFS及BFS對圖的遍歷操作;瞭解圖結構在人工智慧、工程等領域的廣泛應用。 實驗內容 採用鄰接矩陣和鄰接連結串列其中一種作
2141 資料結構實驗之圖論一:基於鄰接矩陣的廣度優先搜尋遍歷(方法2)
資料結構實驗之圖論一:基於鄰接矩陣的廣度優先搜尋遍歷 Time Limit: 1000MS Memory Limit: 65536KB Problem Description 給定一個無向連通圖,