1、数据结构报告3中南大学数据结构实验报告数据结构实验报告31.实验内容图的操作算法实现图的常用操作算法:包括建立图的存储结构、深度优先搜索和广度优先搜索,求图的最小生成树、拓扑排序、最短路径等。2.程序设计思路 1.最小生成树Prim算法设G = (V,E)是连通带权图,V = 1,2,n。构造G的最小生成树Prim算法的基本思想是:首先置S = 1,然后,只要S是V的真子集,就进行如下的贪心选择:选取满足条件i S,j V S,且cij最小的边,将顶点j添加到S中。这个过程一直进行到S = V时为止。在这个过程中选取到的所有边恰好构成G的一棵最小生成树。Kruskal算法当图的边数为e时,Kr
2、uskal算法所需的时间是O(eloge)。当e = (n2)时,Kruskal算法比Prim算法差;但当e = o(n2)时,Kruskal算法比Prim算法好得多。2.图的深度优先搜索递归实现(1)访问顶点v;visitedv=1;/算法执行前visitedn=0(2)w=顶点v的第一个邻接点;(3)while(w存在) if(w未被访问) 从顶点w出发递归执行该算法; w=顶点v的下一个邻接点;非递归实现 (1)栈S初始化;visitedn=0; (2)访问顶点v;visitedv=1;顶点v入栈S (3)while(栈S非空) x=栈S的顶元素(不出栈); if(存在并找到未被访问的x
3、的邻接点w) 访问w;visitedw=1; w进栈;3.拓扑排序(1)在AOV网络中选一个没有直接前驱的顶点, 并输出之;(2)从图中删去该顶点, 同时删去所有它发出的有向边;(3)重复以上步骤, 直到全部顶点均已输出,拓扑有序序列形成,拓扑排序完成;或者图中还有未输出的顶点,但已跳出处理循环。这说明图中还剩下一些顶点,它们都有直接前驱,再也找不到没有前驱的顶点了。这时AOV网络中必定存在有向环。(拓扑排序完成;AOV网络中必定存在有向环)4.了解了最短路径算法 单源最短路径问题:已知有向带权图(简称有向网)G=(V,E),找出从某个源点sV到V中其余各顶点的最短路径。迪杰斯特拉(Dijks
4、tra)算法求单源最短路径。3.主要算法1、最小生成树#include#include#include#define MAX_VERTEX_NUM 20#define OK 1#define ERROR 0#define MAX 1000using namespace std;typedef struct Arcell double adj;Arcell,AdjMatrixMAX_VERTEX_NUMMAX_VERTEX_NUM;typedef struct char vexsMAX_VERTEX_NUM; /节点数组 AdjMatrix arcs; /邻接矩阵 int vexnum, arc
5、num; /图的当前节点数和弧数MGraph;typedef struct Pnode /用于普利姆算法 char adjvex; /节点 double lowcost; /权值Pnode,ClosedgeMAX_VERTEX_NUM; /记录顶点集U到V-U的代价最小的边的辅助数组定义typedef struct Knode /用于算法中存储一条边及其对应的2个节点 char ch1; /节点1 char ch2; /节点2 double value;/权值Knode,DgevalueMAX_VERTEX_NUM;int CreateUDG(MGraph & G,Dgevalue & dge
6、value) /构造无向加权图的邻接矩阵 int i,j,k; coutG.vexnumG.arcnum; cout请输入节点:; for(i=0;iG.vexsi; for(i=0;iG.vexnum;+i)/初始化数组 for(j=0;jG.vexnum;+j) G.arcsij.adj=MAX; cout请输入一条边依附的定点及边的权值:endl; for(k=0;k dgevaluek.ch1 dgevaluek.ch2 dgevaluek.value; i = LocateVex(G,dgevaluek.ch1 ); j = LocateVex(G,dgevaluek.ch2 );
7、G.arcsij.adj = dgevaluek.value; G.arcsji.adj = G.arcsij.adj; return OK;int LocateVex(MGraph G,char ch) /确定节点ch在图G.vexs中的位置 int a ; for(int i=0; iG.vexnum; i+) if(G.vexsi = ch) a=i; return a;/typedef struct Pnode /用于普利姆算法/ char adjvex; /节点/ double lowcost; /权值/Pnode,ClosedgeMAX_VERTEX_NUM; /记录顶点集U到V-
8、U的代价最小的边的辅助数组定义void MiniSpanTree_PRIM(MGraph G,char u)/普利姆算法求最小生成树 int i,j,k; Closedge closedge; k = LocateVex(G,u); for(j=0; jG.vexnum; j+) if(j != k) closedgej.adjvex = u; closedgej.lowcost = G.arcskj.adj; closedgek.lowcost = 0; for(i=1; iG.vexnum; i+) k = Minimum(G,closedge);cout(closedgek.adjvex
9、,G.vexsk,closedgek.lowcost)endl; closedgek.lowcost = 0; for(j=0; jG.vexnum; +j) if(G.arcskj.adj closedgej.lowcost) closedgej.adjvex = G.vexsk; closedgej.lowcost= G.arcskj.adj; int Minimum(MGraph G,Closedge closedge) /求closedge中权值最小的边,并返回其顶点在vexs中的位置 int i,j; double k = 1000; for(i=0; iG.vexnum; i+)
10、if(closedgei.lowcost != 0 & closedgei.lowcost k) k = closedgei.lowcost; j = i; return j;void MiniSpanTree_KRSL(MGraph G,Dgevalue & dgevalue)/克鲁斯卡尔算法求最小生成树 int p1,p2,i,j; int bjMAX_VERTEX_NUM; /标记数组 for(i=0; iG.vexnum; i+) /标记数组初始化 bji=i; Sortdge(dgevalue,G);/将所有权值按从小到大排序 for(i=0; iG.arcnum; i+) p1 =
11、 bjLocateVex(G,dgevaluei.ch1); p2 = bjLocateVex(G,dgevaluei.ch2); if(p1 != p2) cout(dgevaluei.ch1,dgevaluei.ch2,dgevaluei.value)endl; for(j=0; jG.vexnum; j+) if(bjj = p2) bjj = p1; void Sortdge(Dgevalue & dgevalue,MGraph G)/对dgevalue中各元素按权值按从小到大排序 int i,j; double temp; char ch1,ch2; for(i=0; iG.arcn
12、um; i+) for(j=i; j dgevaluej.value) temp = dgevaluei.value; dgevaluei.value = dgevaluej.value; dgevaluej.value = temp; ch1 = dgevaluei.ch1; dgevaluei.ch1 = dgevaluej.ch1; dgevaluej.ch1 = ch1; ch2 = dgevaluei.ch2; dgevaluei.ch2 = dgevaluej.ch2; dgevaluej.ch2 = ch2; void main() int i,j; MGraph G; char
13、 u; Dgevalue dgevalue; CreateUDG(G,dgevalue); cout图的邻接矩阵为:endl; for(i=0; iG.vexnum; i+) for(j=0; jG.vexnum; j+) cout G.arcsij.adj ; coutendl; cout=普利姆算法=n; coutu; cout构成最小代价生成树的边集为:n; MiniSpanTree_PRIM(G,u); cout=克鲁斯科尔算法=n; cout=S.stacksize) S.base=(SElemType*)realloc(S.base,(S.stacksize+STACKINCREM
14、ENT)*sizeof(SElemType); if(!S.base) exit(-1); S.top=S.base+S.stacksize; S.stacksize+=STACKINCREMENT; /if *(S.top)=e; S.top+; return 1;/Pushint Pop(SqStack &S,SElemType &e)if(S.top=S.base) return 0;-S.top;e=*S.top;return 1;/Popint StackEmpty(SqStack &S)if(S.top=S.base) return 1;else return 0;/StackEm
15、ptyint LocateVex(ALGraph G,char u) int i; for (i=0;iG.vexnum;i+) if(u=G.verticesi.data) return i; if (i=G.vexnum) printf(Error u!n);exit(1); return 0; void CreateALGraph_adjlist(ALGraph &G) int i,j,k,w; char v1,v2,enter; ArcNode *p; printf(Input vexnum & arcnum:n); scanf(%d,&G.vexnum); scanf(%d,&G.a
16、rcnum); printf(Input Vertices(以回车隔开各个数据):n); for (i=0;iG.vexnum;i+) scanf(%c%c,&enter,&G.verticesi.data);/注意点,解说 G.verticesi.firstarc=NULL; /forprintf(Input Arcs(v1,v2,w)以回车分开各个数据:n); for (k=0;kadjvex=j; p-info = w; p-nextarc=G.verticesi.firstarc; /前插法,即每次都插入到头结点的后面 G.verticesi.firstarc=p; printf(Ne
17、xtn); /for return;/CreateALGraph_adjlistvoid FindInDegree(ALGraph &G)int i,j;for(i=0;iG.vexnum;i+) G.verticesi.count=0; /forfor(j=0;jnextarc) G.verticesp-adjvex.count+; /for/FindInDegreeint TopoSort(ALGraph &G)SqStack S;FindInDegree(G);InitStack(S);for(int i=0;inextarc) int k; k=p-adjvex; if(!(-G.ve
18、rticesk.count) Push(S,k); /for /while if(counttG.vexnum) return 0; else return 1;/TopoSortint main()ALGraph G;CreateALGraph_adjlist(G);TopoSort(G);return 1;3、深度优先搜索和广度优先搜索深度优先搜索:图的深度优先遍历类似于树的前序遍历。采用的搜索方法的特点是尽可能先对纵深方向进行搜索。这种搜索方法称为深度优先搜索广度优先搜索:图的广度优先遍历BFS算法是一个分层搜索的过程,和树的层序遍历算法类同,它也需要一个队列以保持遍历过的顶点顺序,以便
19、按出队的顺序再去访问这些顶点的邻接顶点。 #include#include#include#define MAX_VERTEX_NUM 20typedef struct ArcNode int adjvex; struct ArcNode* nextarc; /InfoType* info;ArcNode;typedef struct LinkNode ArcNode* parc; /存储指针地址 struct LinkNode* next; /指向一下个结点LinkNode;typedef struct VNode char cData; /顶点元素值 ArcNode* firstarc;
20、/指向第一条依附于该点的边VNode,AdjListMAX_VERTEX_NUM;typedef struct AdjList vertices; int vexnum; /图的当前顶点数和弧数 int arcnum; ALGraph;int VisitedMAX_VERTEX_NUM;int PrintCheck(ALGraph* pag) int i; ArcNode* p; printf(nCheck the Graph!n); printf(Notdatatnexttnextt.n); for(i=0; ivexnum; i+) printf(%dt%ct,i,pag-vertices
21、i.cData); p = pag-verticesi.firstarc; while(p) printf(%dt,p-adjvex); p = p-nextarc; printf(n); return 1;int CreateGraph(ALGraph* pag,int start,int end) ArcNode* arcNodes = (ArcNode*)malloc(sizeof(ArcNode); ArcNode* arcNodee = (ArcNode*)malloc(sizeof(ArcNode); ArcNode* p; if(!arcNodes | !arcNodee) re
22、turn 0;/从start-end生成关系 arcNodes-adjvex = end; /下一结点的位置 p = pag-verticesstart.firstarc; if(!p) /第一个结点单独构造 arcNodes-nextarc = pag-verticesstart.firstarc; pag-verticesstart.firstarc = arcNodes; else while(p-nextarc) p = p-nextarc; p-nextarc = arcNodes; arcNodes-nextarc = NULL; /end-start 的关系生成 arcNodee
23、-adjvex = start; /下一结点的位置 p = pag-verticesend.firstarc; if(!p) /第一个结点单独构造 arcNodee-nextarc = pag-verticesend.firstarc; pag-verticesend.firstarc = arcNodee; else while(p-nextarc) p = p-nextarc; p-nextarc = arcNodee; arcNodee-nextarc = NULL; return 1;void DFSTraverse(ALGraph ag,int start) LinkNode* Stack = (LinkNode*)mal
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1