徐州工程学院数据结构最小生成树实验文档

合集下载

最小生成树 实验报告

最小生成树 实验报告

最小生成树实验报告最小生成树实验报告一、引言最小生成树是图论中的一个重要概念,它在实际问题中有着广泛的应用。

本次实验旨在通过编程实现最小生成树算法,并通过实验数据对算法进行分析和评估。

二、算法介绍最小生成树算法的目标是在给定的带权无向图中找到一棵生成树,使得树上所有边的权重之和最小。

本次实验我们选择了两种经典的最小生成树算法:Prim 算法和Kruskal算法。

1. Prim算法Prim算法是一种贪心算法,它从一个顶点开始,逐步扩展生成树的规模,直到包含所有顶点为止。

算法的具体步骤如下:(1)选择一个起始顶点,将其加入生成树中。

(2)从与生成树相邻的顶点中选择一个权重最小的边,将其加入生成树中。

(3)重复上述步骤,直到生成树包含所有顶点。

2. Kruskal算法Kruskal算法是一种基于并查集的贪心算法,它首先将图中的边按权重从小到大进行排序,然后逐个加入生成树中,直到生成树包含所有顶点为止。

算法的具体步骤如下:(1)将图中的边按权重从小到大进行排序。

(2)逐个加入边,如果该边的两个顶点不在同一个连通分量中,则将其加入生成树中。

(3)重复上述步骤,直到生成树包含所有顶点。

三、实验过程本次实验我们使用C++语言实现了Prim算法和Kruskal算法,并通过随机生成的图数据进行了测试。

1. Prim算法的实现我们首先使用邻接矩阵表示图的结构,然后利用优先队列来选择权重最小的边。

具体实现过程如下:(1)创建一个优先队列,用于存储生成树的候选边。

(2)选择一个起始顶点,将其加入生成树中。

(3)将与生成树相邻的顶点及其边加入优先队列。

(4)从优先队列中选择权重最小的边,将其加入生成树中,并更新优先队列。

(5)重复上述步骤,直到生成树包含所有顶点。

2. Kruskal算法的实现我们使用并查集来维护顶点之间的连通关系,通过排序后的边序列来逐个加入生成树中。

具体实现过程如下:(1)将图中的边按权重从小到大进行排序。

最小生成树 实验报告

最小生成树 实验报告

最小生成树(Minimum Spanning Tree)实验报告1. 实验目的本实验旨在通过实践掌握最小生成树算法的基本原理和实现方法。

最小生成树是图论中的一个重要概念,用于解决具有权重的连通图的最优路径问题。

通过本实验,我们将学习如何使用最小生成树算法找到一棵连接图的所有节点且总权重最小的树。

2. 实验原理最小生成树是一个连通图的一种生成树,它的所有边的权重之和最小。

最小生成树的求解算法有多种,其中两种常用的算法是 Prim 算法和 Kruskal 算法。

2.1 Prim 算法Prim 算法是一种贪心算法,从一个节点开始,逐步扩展最小生成树的边。

具体步骤如下: 1. 选择一个起始节点作为最小生成树的根节点。

2. 在当前最小生成树的所有节点中选择一个与该树相连接的权重最小的边,将其加入最小生成树。

3. 将该节点标记为已访问。

4. 重复步骤 2 和步骤 3,直到所有节点都被访问。

2.2 Kruskal 算法Kruskal 算法也是一种贪心算法,通过不断选择权重最小的边来构建最小生成树。

具体步骤如下: 1. 对所有边按照权重进行排序。

2. 依次选择权重最小的边,如果该边的两个端点不在同一个连通分量中,则将该边加入最小生成树,并将这两个端点合并到同一个连通分量中。

3. 重复步骤 2,直到所有节点都在同一个连通分量中,即最小生成树构建完成。

3. 实验步骤本实验将使用 Prim 算法和 Kruskal 算法分别求解给定图的最小生成树。

3.1 数据准备首先,我们需要准备一个具有权重的连通图作为实验数据。

假设该图有 n 个节点和 m 条边,我们可以使用邻接矩阵或邻接表来表示这个图。

3.2 Prim 算法求解最小生成树1.首先,选择一个起始节点作为最小生成树的根节点,并将该节点标记为已访问。

2.初始化一个空的最小生成树,用于存储最终的结果。

3.重复以下步骤,直到所有节点都被访问:1.在当前最小生成树的所有节点中选择一个与该树相连接的权重最小的边,将其加入最小生成树。

求最小生成树(Kruskal算法)实验报告

求最小生成树(Kruskal算法)实验报告

求最小生成树(Kruskal算法)实验报告一、实验目的通过本次实验,掌握Kruskal算法的基本原理,能够使用该算法求解最小生成树问题,并能够进行实际应用。

同时,为学习算法的设计和分析打下基础。

二、实验内容1. 理解Kruskal算法的基本原理。

2. 实现Kruskal算法,并将其应用于求解最小生成树问题。

3. 设计实验测试用例,验证程序正确性并进行性能分析。

三、实验原理Kruskal算法是最小生成树问题的一种解决方法。

该算法基于贪心策略,通过不断选择最短的边来构造最小生成树。

实现步骤如下:1. 将所有边按权重从小到大进行排序。

2. 遍历所有边,每次选择一条没有出现在生成树中的最短边,并将该边所连接的两个顶点合并到同一连通分量中。

3. 直到所有的边都被遍历过,即可得到最小生成树。

四、实验设计本次实验的主要任务是实现Kruskal算法,并运用到最小生成树问题中。

为了测试算法的正确性和性能,需要设计适当的测试用例。

具体的实验步骤如下:1. 设计数据结构在Kruskal算法中,需要维护边的信息,并对边进行排序,同时需要维护顶点的信息。

为方便实现,可以使用C++语言的STL库中的vector和set数据结构。

vector用于存储顶点信息,set用于存储排序后的边信息。

其中,顶点包含顶点编号和连通分量编号,边包含起点、终点和边权重。

为了方便生成测试数据,定义两个常量:MAX_VERTEX和MAX_EDGE。

MAX_VERTEX表示最大顶点数量,MAX_EDGE表示最大边数量。

2. 生成测试数据为了测试算法的正确性和性能,需要生成不同大小的测试数据。

可以随机生成若干个顶点和相应的边,其中顶点编号从1开始连续编号,边的起点和终点使用随机数生成,边的权重也使用随机数生成。

3. 实现Kruskal算法根据算法原理,可以实现基本的Kruskal算法。

具体实现过程如下:1. 首先将所有的边按照权重从小到大排序,并分别初始化每个顶点的连通分量编号。

最小生成树实验报告材料

最小生成树实验报告材料

数据结构课程设计报告题目:最小生成树问题院(系):计算机工程学院学生姓名:班级:学号:起迄日期:指导教师:2011—2012年度第2 学期一、需求分析1.问题描述:在n个城市之间建设网络,只需保证连通即可,求最经济的架设方法。

存储结构采用多种。

求解算法多种。

2.基本功能在n个城市之间建设网络,只需要架设n-1条线路,建立最小生成树即可实现最经济的架设方法。

程序可利用克鲁斯卡尔算法或prim算法生成最小生成树。

3.输入输出以文本形式输出最小生成树,同时输出它们的权值。

通过人机对话方式即用户通过自行选择命令来输入数据和生成相应的数据结果。

二、概要设计1.设计思路:因为是最小生成树问题,所以采用了课本上介绍过的克鲁斯卡尔算法和prim算法两种方法来生成最小生成树。

根据要求,需采用多种存储结构,所以我选择采用了邻接表和邻接矩阵两种存储结构。

2.数据结构设计:图状结构:ADT Graph{数据对象V:V是具有相同特性的数据元素的集合,称为顶点集。

数据关系R:R={VR}VR={<v,w>|v,w∈V且P(v,w),<v,w>表示从v到w的弧,谓词P(v,w)定义了弧<v,w>的意义或信息}基本操作:CreateGraph( &G, V, VR )初始条件:V是图的顶点集,VR是图中弧的集合。

操作结果:按V和VR的定义构造图G。

DestroyGraph( &G )初始条件:图G存在。

操作结果:销毁图G。

LocateVex( G, u )初始条件:图G存在,u和G中顶点有相同特征。

操作结果:若G中存在顶点u,则返回该顶点在图中位置;否则返回其它信息。

GetVex( G, v )初始条件:图G存在,v是G中某个顶点。

操作结果:返回v的值。

PutVex( &G, v, value )初始条件:图G存在,v是G中某个顶点。

操作结果:对v赋值value。

FirstAdjVex( G, v )初始条件:图G存在,v是G中某个顶点。

徐州工程学院数据结构实验报告

徐州工程学院数据结构实验报告

徐州工程学院管理学院实验报告实验课程名称:数据结构与算法实验地点:经济管理实验中心年月至年月专业信息管理与信息系统班级学生姓名学号指导老师实验报告实验项目:线性表及其应用实验学时: 2实验日期:实验要求:熟悉并掌握单链表的存储及基本算法的使用实验内容:单链表就地逆置代码如下:#include<stdio.h>#include<stdlib.h>typedef struct LNode{int data;struct LNode *next;}LNode, *LinkList;LNode *p106,*head106;LNode *s106,*l106,*d106;int n;int m=sizeof(LNode);void ListCreate(){int i106;head106=(LinkList)malloc(m);p106=head106;for(i106=1;i106<5;i106++){p106->data=i106;p106->next=(LinkList)malloc(m);p106=p106->next;}p106->data=5;p106->next=NULL;}void ListOutput(){p106=head106;while(p106->next!=NULL){printf("%d",p106->data);p106=p106->next;}printf("%d\n",p106->data);}void ListChange(){LNode *q106,*l106;p106=head106;l106=p106->next;while(l106!=NULL){q106=l106->next;l106->next=p106;p106=l106;l106=q106;}head106->next=NULL;head106=p106;}void ListFinal(){p106=head106;while(p106->next!=NULL){printf("%d",p106->data);p106=p106->next;}printf("%d\n",p106->data);}int main(){ListCreate();ListOutput();ListChange();ListFinal();getch();}运行结果如下:实验项目:栈的应用实验学时: 2实验日期:实验要求:熟悉并掌握利用栈的特性进行相关运算实验内容::双向栈的应用代码如下:#include <stdio.h>#include <stdlib.h>#include <malloc.h>#define OK 1#define ERROR 0#define OVERFLOW -1typedef int Elemtype;typedef struct{ int *base[2]; int *top[2];}*BDStacktype;Init_BDStack(BDStacktype tws,int m){(*tws).base[0]=(Elemtype*)malloc(m*sizeof(Elemtype)); (*tws).base[1]=(*tws).base[0]+((m-1)*sizeof(Elemtype)); (*tws).top[0]=(*tws).base[0];(*tws).top[1]=(*tws).base[1];return OK;}push(BDStacktype tws,int i106,Elemtype x) {if((*tws).top[0]>(*tws).top[1]) return OVERFLOW;if(i106==0) *(*tws).top[0]++=x;else if(i106==1){ if((*tws).top[1]==(*tws).base[1]) return OVERFLOW;*x=*++(*tws).top[1];}else return ERROR;return OK; }printBDStack(BDStacktype tws){Elemtype *p;p=(*tws).base[0];printf("Now the 0 Stack is:");Elemtype *p;p=(*tws).base[0];printf("Now the 0 Stack is:");while(p!=(*tws).top[0])printf("%d",*p++);printf("\n");p=(*tws).base[1];printf("Now the 1 Stack is:");while(p!=(*tws).top[1])printf("%d",*p--);printf("\n");}void main(){int m=0; int t=0,n;Elemtype *e; int i106;BDStacktype s;printf("Input the size of BDStack :");scanf("%d",m);Init_BDStack(s,m);printf("Input the total num of push:");scanf("%d",&t);for(i106=1;i106<t+1;i106++){printf("Input the %dth stack No.and data of push:",i);scanf("%d,%d",&n,e);push(s,n,*e); }printBDStack(s);printf("Input the stack No. which you will pop:");scanf("%d",&n);pop(s,n,e);printf("Pop the %dth stack,the num is:%d\n",n,*e);printBDStack(s);printf("\n");getch();}(2)结果实验项目:数组的应用实验学时:4实验日期:实验要求:熟悉并掌握矩阵压缩存储的算法实验内容:矩阵压缩存储代码如下:#include<stdlib.h>typedef int ElemType;#define MAXSIZE 100typedef struct{int i,j;ElemType e;}Triple;typedef struct{Triple data[MAXSIZE+1];int mu106,nu,tu;}TSMatrix;int CreateSMatrix(TSMatrix *M){int i,m,n;ElemType e;int k;printf("hang,lie,feiling geshu:\n");scanf("%d,%d,%d",&(*M).mu106,&(*M).nu,&(*M).tu);(*M).data[0].i=0;for(i = 1; i <= (*M).tu; i++){do{printf("%dgefeilingyuansuozaide hang(1-%d), lie(1-%d),yuansuzhi:\n", i,(*M).mu106,(*M).nu);scanf("%d,%d,%d",&m,&n,&e);k=0;if(m < 1 || m > (*M).mu106|| n < 1 || n > (*M).nu)k=1;if(m <(*M).data[i-1].i || m ==(*M).data[i-1].i && n <= (*M).data[i-1].j) k=1;}while(k);(*M).data[i].i = m;(*M).data[i].j = n;(*M).data[i].e = e;}(*M).data[i].i = m;(*M).data[i].j = n;(*M).data[i].e = e;}return 1;}void PrintSMatrix(TSMatrix M){int x,y,z;int k;for(x=1;x<=M.mu106;x++){for(y=1;y<=M.nu;y++){k=0;for(z=1;z<=M.tu;z++){if((M.data[z].i==x) && (M.data[z].j==y)){ printf("%4d",M.data[z].e);k=1;}}if(k==0){printf("%4d",k);}}printf("\n");}}int main(){TSMatrix A;CreateSMatrix(&A);PrintSMatrix(A);getch();}(2)结果:实验项目:树的应用实验学时:2实验日期:实验要求:熟悉并掌握建立树及利用二叉树遍历算法进行其他操作实验内容:二叉树的叶子结点计算代码如下:#include "stdio.h"#include "conio.h"typedef struct Node{char data;struct Node *lchild,*rchild;}BiTNode;crt_bt_pre106(){BiTNode *T;char ch;printf("ch==");scanf("%c",&ch);if(ch==' ')T=NULL;else{T=(BiTNode*) malloc (sizeof(BiTNode));T->data=ch;T->lchild=crt_bt_pre106(T->lchild);T->rchild=crt_bt_pre106(T->rchild);}return T;}void preorder106 (BiTNode *T){if(T!=NULL){printf("%c",T->data);preorder106(T->lchild);preorder106(T->rchild);}}int leafCount106(BiTNode *T){if(!T) return 0;else if (!T->lchild && !T->rchild) return 1;else return leafCount106(T->lchild) + leafCount106(T->rchild); }void main(){BiTNode *root;printf("creat erchashu:");root=crt_bt_pre106();printf("\n");printf("preorder:");printf("\n");preorder106(root);printf("\n");printf("count is %d\n",leafCount106(root));getch();}(2)结果:实验项目:图的应用实验学时:2实验日期:实验要求:熟悉并掌握图的构造算法的使用实验内容:有向图的邻接表存储代码如下:#include "stdio.h"typedef struct e_node{ int adjvex;struct e_node *next ;}E_NODE;E_NODE *q106;E_NODE *p106;typedef struct v_node{ int vertex;E_NODE *link;}V_NODE;V_NODE head[20];void creat_adj_list(V_NODE head[], int t, int n) {int i106;int e106;int w106;int v106;w106=1,v106=1;for(i106=1;i106<=n;i106++){ head[i106].link=NULL;head[i106].vertex=i106;}printf("the sidenumber is: e=");scanf("%d",&e106);for(i106=1;i106<=e106;i106++){printf("v=");scanf("%d",&v106);printf("w=");scanf("%d",&w106);if((v106<=n)&&(w106<=n)){if(t==1){p106=(E_NODE *)malloc(sizeof(E_NODE));p106->adjvex=w106;p106->next=head[v106].link;head[v106].link=p106;}if(t==0){ p106=(E_NODE *)malloc(sizeof(E_NODE));p106->adjvex=v106;p106->next=head[w106].link;head[w106].link=p106;}}}printf("the content : \n");for(i106=1;i106<=n;i106++){q106=head[i106].link;printf("the number %d vertex =>",i106); while(q106!=NULL){printf("%d",q106->adjvex);q106=q106->link;}printf("\n");}}void main(){int t;int n;printf("t=");scanf("%d",&t);printf("the number of vertex :");scanf("%d",&n);creat_adj_list(head,t,n);getch();}结果:实验项目:查找和排序算法应用实验学时: 4实验日期:实验要求:熟悉并掌握查找和排序算法的使用实验内容:对某字符串进行排序,并在此基础上利用查找算法进行查找代码如下:#include "stdio.h"typedef struct {char key;}create;create st[26];void build(){printf("please input the letters:");gets(st);}void change(){int t106;int i106;int j106;for(j106=0;j106<25;j106++){for(i106=0;i106<25-j106;i106++){if(st[i106].key>st[i106+1].key){t106=st[i106].key;st[i106].key=st[i106+1].key;st[i106+1].key=t106;}}}printf("the right order is:");for(i106=0;i106<26;i106++){printf("%c",st[i106]);}}int binsrch(create st[],char k){int low,high,mid, found;low=0; high=25; found=0;while((low<=high) &&(found==0)){mid=(low+high)/2;if(k>st[mid].key) low=mid+1;else if(k==st[mid].key) found=1; else high=mid-1;}if(found==1) return(mid);else return(-1);}int main(){int n;char k;build();change();printf("\nthe letter needed found is:"); scanf("%c",&k);n=binsrch(st,k);printf("the location is: %d",n+1);getch();}(2)结果:。

最小生成树实验报告

最小生成树实验报告

最小生成树实验报告最小生成树实验报告引言:最小生成树是图论中一个重要的概念,它在许多实际问题中都有广泛的应用。

本次实验旨在通过实际操作,深入理解最小生成树的概念、算法及其在实际问题中的应用。

本文将从实验的目的、实验过程、实验结果及分析等方面进行详细的论述。

实验目的:1. 理解最小生成树的概念及其在实际问题中的应用;2. 掌握最小生成树的两种常用算法:Prim算法和Kruskal算法;3. 通过实际操作,加深对最小生成树算法的理解。

实验过程:1. 实验环境的搭建:首先,我们需要在计算机上搭建一个图论实验环境。

选择一门编程语言,如Python,来实现最小生成树算法。

通过安装相应的开发环境和图论库,我们可以方便地进行实验。

2. 数据的准备:为了进行最小生成树的实验,我们需要准备一组具有权值的图数据。

可以通过手动输入或从文件中读取的方式获取数据。

确保数据的合理性和完整性,以便进行后续的实验操作。

3. Prim算法的实现:Prim算法是一种贪心算法,用于求解最小生成树。

在实验中,我们需要实现Prim算法,并将其应用于准备好的图数据上。

通过编程实现,我们可以得到Prim算法生成的最小生成树。

4. Kruskal算法的实现:Kruskal算法是另一种常用的最小生成树算法。

与Prim算法不同,Kruskal算法是一种基于边的贪心算法。

同样地,我们需要实现Kruskal算法,并将其应用于准备好的图数据上,以获得Kruskal算法生成的最小生成树。

实验结果与分析:通过实验,我们得到了Prim算法和Kruskal算法生成的最小生成树。

我们可以将这两个结果进行对比和分析,以进一步理解这两种算法的特点和应用场景。

首先,我们可以比较两个算法生成的最小生成树的权值。

通过计算权值的总和,我们可以确定哪个算法生成的最小生成树更优。

此外,我们还可以比较两个算法生成的最小生成树的结构,观察它们是否存在差异。

其次,我们可以分析两个算法的时间复杂度和空间复杂度。

数据结构实验指导书及答案(徐州工程学院)

数据结构实验指导书及答案(徐州工程学院)

《数据结构实验》实验指导书及答案信电工程学院计算机科学和技术教研室编2011.12数据结构实验所有代码整理作者郑涛声明:在这里我整理了数据结构实验的所有代码,希望能对大家的数据结构实验的考试有所帮助,大家可以有选择地浏览,特别针对一些重点知识需要加强记忆(ps:重点知识最好让孙天凯给出),希望大家能够在数据结构实验的考试中取得令人满意的成绩,如果有做的不好的地方请大家谅解并欢迎予以指正。

实验一熟悉编程环境实验预备知识:1.熟悉本课程的语言编译环境(TC或VC),能够用C语言编写完整的程序,并能够发现和改正错误。

2.能够灵活的编写C程序,并能够熟练输入C程序。

一、实验目的1.熟悉C语言编译环境,掌握C程序的编写、编译、运行和调试过程。

2.能够熟练的将C程序存储到指定位置。

二、实验环境⒈硬件:每个学生需配备计算机一台。

⒉软件:Windows操作系统+Turbo C;三、实验要求1.将实验中每个功能用一个函数实现。

2.每个输入前要有输入提示(如:请输入2个整数当中用空格分割:),每个输出数据都要求有内容说明(如:280和100的和是:380。

)。

3.函数名称和变量名称等用英文或英文简写(每个单词第一个字母大写)形式说明。

四、实验内容1.在自己的U盘中建立“姓名+学号”文件夹,并在该文件夹中创建“实验1”文件夹(以后每次实验分别创建对应的文件夹),本次实验的所有程序和数据都要求存储到本文件夹中(以后实验都按照本次要求)。

2.编写一个输入某个学生10门课程成绩的函数(10门课程成绩放到结构体数组中,结构体包括:课程编号,课程名称,课程成绩)。

3.编写一个求10门成绩中最高成绩的函数,输出最高成绩和对应的课程名称,如果有多个最高成绩,则每个最高成绩均输出。

4.编写一个求10门成绩平均成绩的函数。

5.编写函数求出比平均成绩高的所有课程及成绩。

#include<stdio.h>#include<conio.h>struct subject{int subject_id;char subject_name[20];double subject_grades;};struct subject sub[10];void input(){int i;printf("please input:\n");for(i=0;i<10;i++){scanf("%d %s %lf",&sub[i].subject_id,&sub[i].subject_name,&sub[i].subject_g rades);}printf("you just input:\n");for(i=0;i<3;i++){printf("%d %s %lf\n",sub[i].subject_id,sub[i].subject_name,sub[i].subject_g rades);}}void subject_max(){int i,flag;double max=sub[0].subject_grades;for(i=0;i<10;i++){if(sub[i].subject_grades>max)max=sub[i].subject_grades;flag=i;}printf("The high score of subjectis %s %lf\n",sub[flag].subject_name,max);}void subject_average(){int i;double average,sum=sub[0].subject_grades;for(i=1;i<10;i++){sum+=sub[i].subject_grades;}average=sum/10;printf("subject's average is %lf\n",average);}void subjct_gtaverage(){int i,flag;double average,sum=sub[0].subject_grades;for(i=1;i<10;i++){sum+=sub[i].subject_grades;}average=sum/10;for(i=0;i<10;i++){if(sub[i].subject_grades>average){flag=i;printf("subject greater than average is %s %lf\n",sub[flag].subject_name,sub[flag].subject_grades);}}}int main(){input();subject_max();subject_average();subjct_gtaverage();return 0;}实验二顺序表的基本操作实验预备知识:1.熟练运用数组进行程序设计,掌握数组名和指针作为函数参数。

数据结构实验报告-最小生成树(精选5篇)

数据结构实验报告-最小生成树(精选5篇)

数据结构实验报告-最小生成树(精选5篇)第一篇:数据结构实验报告-最小生成树电子科技大学实验报告学生姓名:XXX 学号:20***指导教师:刘峤实验地点:信软楼306实验时间:5月17日一、实验室名称:软件实验室二、实验项目名称:数据结构与算法—图三、实验学时:4四、实验原理:Kruskal 算法是一种按照图中边的权值递增的顺序构造最小生成树的方法。

其基本思想是:设无向连通网为G=(V,E),令G 的最小生成树为T,其初态为T=(V,{}),即开始时,最小生成树T 由图G 中的n 个顶点构成,顶点之间没有一条边,这样T 中各顶点各自构成一个连通分量。

然后,按照边的权值由小到大的顺序,考察G 的边集E 中的各条边。

若被考察的边的两个顶点属于T 的两个不同的连通分量,则将此边作为最小生成树的边加入到T 中,同时把两个连通分量连接为一个连通分量;若被考察边的两个顶点属于同一个连通分量,则舍去此边,以免造成回路,如此下去,当T 中的连通分量个数为1 时,此连通分量便为G 的一棵最小生成树。

如教材153页的图4.21(a)所示,按照Kruskal 方法构造最小生成树的过程如图4.21 所示。

在构造过程中,按照网中边的权值由小到大的顺序,不断选取当前未被选取的边集中权值最小的边。

依据生成树的概念,n 个结点的生成树,有n-1 条边,故反复上述过程,直到选取了n-1 条边为止,就构成了一棵最小生成树。

五、实验目的:本实验通过实现最小生成树的算法,使学生理解图的数据结构存储表示,并能理解最小生成树Kruskal 算法。

通过练习,加强对算法的理解,提高编程能力。

六、实验内容:(1)假定每对顶点表示图的一条边,每条边对应一个权值;(2)输入每条边的顶点和权值;(3)输入每条边后,计算出最小生成树;(4)打印最小生成树边的顶点及权值。

七、实验器材(设备、元器件):八、数据结构及程序#include #include #include typedefstruct {intvex;intgno;}TVex,*TpVex;typedefstruct {intvhead, vtail;intwght;intflag;}TEdge,*TpEdge;typedef struct{TpVex VexList;TpEdge EdgeList;int nvex, nedge;}TGraph, *TpGraph;void begin(TpGraph G){ int i;for(i=1;i<=G->nvex;i++){G->VexList[i-1].gno=i;G->EdgeList[i-1].flag=0;} } int findmin(TpGraph G){ int i,j;int minwght=G->EdgeList[0].wght;for(i=0,j=-1;inedge;i++){ PC机一台,装有C/C++语言集成开发环境。

徐州工程学院数据结构最小生成树实验文档

徐州工程学院数据结构最小生成树实验文档

实验九图的最小生成树算法的实现实验预备知识:1.理解图最小生成树的意义和相应算法。

2.掌握带权图的存储结构。

一、实验目的1.使学生熟悉最小生成树的算法实现。

2.掌握带权图的存储结构和处理方法。

二、实验环境⒈硬件:每个学生需配备计算机一台。

操作系统:DOS或Windows;⒉软件:DOS或Windows操作系统+Turbo C;三、实验要求1.能够独立完成带权图的存储和最小生成树的生成四、实验内容1.在自己的U盘的“姓名+学号”文件夹中创建“实验9”文件夹,本次实验的所有程序和数据都要求存储到本文件夹中。

2.现在某电信公司要对如下图的几个城市之间进行光纤连接布线,请用合适的存储结构将下图存储到计算机中方便进行处理。

3.现在公司想以最小的代价将所有城市连通,方便所有城市间通信,请用普里姆算法和克鲁斯卡尔算法实现本图的最小生成树#include <stdio.h>#include <stdlib.h>#define INF 50typedef struct ArcNode{int adjvex; //该弧所指向的顶点位置struct ArcNode *nextarc; //下一个临接点int weight; //弧的权重}ArcNode; //表结点typedef struct VNode{char data; //顶点信息ArcNode *firstarc; //指向下一个结点}VNode,AdjList[6];typedef struct{AdjList LH; //创建头结点数组int vexnum; //图的点的个数int arcnum; //图的边的个数}Graph;typedef struct{char nextvex;int lowcost;int know;}Auxiliary_array; //辅助数组结构体void main (void){void buildtu (Graph*);void printgraph(Graph*);void prim( Graph *G, char u);char u;Graph UDG;Graph *G = &UDG;buildtu(G);printgraph(G); //打印图printf("请输入起始顶点:\n");while(getchar()!='\n');u = getchar();prim(G ,u);}void buildtu (Graph *G) { //建图int search(Graph *G,char a);int i,n1,n2,w;char a,b;ArcNode *p, *q;printf("请输入顶点个数和边的条数:\n");scanf("%d %d",&G->vexnum,&G->arcnum);printf("请输入顶点信息\n");for (i = 0; i < G->vexnum; ++i){while (getchar()!='\n');scanf("%c",&G->LH[i].data);G->LH[i].firstarc = NULL;}printf("请输入有关系的结点和该边的权重:\n");for(i=0;i<G->arcnum;++i){while (getchar()!='\n');scanf("%c %c %d",&a,&b,&w);n1=search(G,a);n2=search(G,b);p=G->LH[n1].firstarc;if(p == NULL){p=G->LH[n1].firstarc=(ArcNode *) malloc (sizeof(ArcNode));}else{while( p->nextarc !=NULL ){p=p->nextarc;}p=p->nextarc=(ArcNode *) malloc (sizeof(ArcNode));}q=G->LH[n2].firstarc;if(q == NULL){q=G->LH[n2].firstarc=(ArcNode *) malloc (sizeof(ArcNode));}else{while( q->nextarc !=NULL ){q=q->nextarc;}q=q->nextarc=(ArcNode *) malloc (sizeof(ArcNode));}p->adjvex=n2;p->weight=w;p->nextarc=NULL;q->adjvex=n1;q->weight=w;q->nextarc=NULL;}}int search (Graph *G,char a){ //确定顶点a在头结点数组中的位置int i;for(i=0;i<G->vexnum;++i){if(G->LH[i].data==a){return i;}}}void printgraph(Graph *G){ //打印图int i;ArcNode *p;for (i=0 ; i < G->vexnum; ++i){p=G->LH[i].firstarc;printf("data:%c \t",G->LH[i].data);while(p!=NULL){printf("firstarc->adjvex=%d",p->adjvex);p=p->nextarc;}printf("\n");}}void prim( Graph *G, char u){//用prim算法实现最小生成树int search (Graph *G,char a);int minimize(Graph *G, Auxiliary_array[]);void printtable(Auxiliary_array[]);Auxiliary_array A[6]; //创建辅助数组int i,j,seat;int location;ArcNode *p ;for (i = 0; i < G->vexnum; ++i) {A[i].nextvex = '0';A[i].know = 0;A[i].lowcost = INF;}location = search(G ,u);//确定u元素在头结点数组中的位置for (p=G->LH[location].firstarc ; p != NULL; p=p->nextarc ){i = p->adjvex;A[i].nextvex = G->LH[location].data;A[i].lowcost = p->weight;A[i].know = 0;}A[location].know = 1;A[location].lowcost = 0;A[location].nextvex = '0';for(j=0;j<G->vexnum-1;++j){seat = minimize( G,A );printf("select min: %d\n", seat);A[seat].know = 1;p=G->LH[seat].firstarc;for (p; p != NULL; p=p->nextarc){i=p->adjvex;if(A[i].know == 0 && p->weight < A[i].lowcost){A[i].nextvex = G->LH[seat].data;A[i].lowcost = p->weight;}}}printtable(A); //打印辅助数组中的信息for (j = 0; j < G->vexnum; ++j)if (j != location)printf("%c<---->%c\n",A[j].nextvex,G->LH[j].data);}int minimize(Graph *G, Auxiliary_array A[]){//取出辅助数组中权值最小的顶点所在的位置int i,place,num;num = INF;for (i = 0; i < G->vexnum; ++i){if(A[i].know == 0 && num >= A[i].lowcost){num = A[i].lowcost;place = i;}}return place;}void printtable(Auxiliary_array A[]) {//打印辅助数组int i;for (i = 0; i < 6; i++) {printf("modifier:%c lowcost:%d known:%d\n", A[i].nextvex, A[i].lowcost, A[i].know);}}实验总结:通过该实验,我深刻明白到了自己对循环的能力不足,书写代码的逻辑性也不够强,相信在以后的学习中能加强这方面的学习,争取在以后的学习中解决这两个方面的问题。

数据结构实验报告最小生成树

数据结构实验报告最小生成树

数据结构实验报告最小生成树实验目的:掌握最小生成树的概念和算法,培养分析和解决实际问题的能力。

实验内容:利用Kruskal算法求解带权无向连通图的最小生成树。

实验原理:最小生成树是指一个连通图的生成树,其中所有边的权值和最小。

最小生成树问题在图论中有着重要的应用,如网络设计、集成电路布线等领域。

本次实验使用Kruskal算法求解最小生成树。

Kruskal算法基于一个贪心的思想:每次选择权值最小的边,直到生成树中包含所有的节点。

具体算法如下:1.根据给定的连通图构造一个边的集合E,E中包含图中所有的边。

2.将E中的边按照权值从小到大排序。

3.依次遍历排序后的边,如果该边的两个节点不在同一个连通分量中,则选择该边,并将这两个节点合并到一个连通分量中。

4.重复第3步,直到生成树中包含所有的节点。

实验步骤及结果:1.根据给定的连通图构造边的集合E,并将E中的边按照权值从小到大排序。

2.初始化一个空的集合T作为最小生成树的边集合。

3.依次遍历排序后的边,如果该边的两个节点不在同一个连通分量中,则选择该边,并将这两个节点合并到一个连通分量中,同时将该边添加到集合T中。

4.重复第3步,直到生成树中包含所有的节点。

实验结果分析:通过Kruskal算法,可以得到带权无向连通图的最小生成树。

最小生成树具有多个优点,如能够保证连通、权值最小、无回路。

在实际应用中,最小生成树常常用于网络设计、集成电路布线等领域。

实验总结:通过本次实验,我掌握了最小生成树的概念和Kruskal算法的原理和实现方法。

实验中,我通过定义边的数据结构和构造边的集合,实现了Kruskal算法求解最小生成树。

通过实验,我深刻认识到数据结构在解决实际问题中的重要性和实用性。

最小生成树作为一种常用的图论算法,在实际应用中具有广泛的应用和重要的价值。

掌握了最小生成树的概念和算法,我相信能够在今后的学习和工作中更好地应用数据结构算法解决实际问题。

最小生成树实验报告

最小生成树实验报告

最小生成树实验报告1.引言最小生成树(Minimum Spanning Tree,简称MST)是图论中的重要概念,在各个领域都有广泛的应用。

最小生成树是指在给定的加权连通图中,选择一个子集,使得该子集包含了所有的顶点,并且所有边的权值之和最小。

本实验主要目的是探讨最小生成树的算法并比较它们的效率和准确性。

2.实验方法本次实验使用Python编程语言实现了两种著名的最小生成树算法:Prim算法和Kruskal算法。

Prim算法是一种贪心算法,从一个顶点开始不断扩张集合,直到包含所有顶点,生成最小生成树。

Kruskal算法则是基于并查集的算法,将边按照权值排序后逐一加入生成树,同时要保证加入的边不会产生环路。

3.实验过程首先,我们从文件中读取了一张加权无向图的数据。

图的表示采用邻接矩阵的方式,即用一个二维数组来存储顶点之间的连接关系和权值。

读取完图的数据后,我们分别使用Prim算法和Kruskal算法求解最小生成树。

在Prim算法中,我们使用一个辅助数组来记录顶点是否已被访问过,然后从任意一个顶点开始,依次将与当前集合相邻的顶点加入,并选择权值最小的边。

直到所有顶点都被访问过,并形成了一个最小生成树。

在Kruskal算法中,我们首先将所有边按照权值从小到大进行排序。

然后,从权值最小的边开始,逐一将边加入生成树。

加入时,需要判断两个顶点是否在同一个连通分量中,以避免产生环路。

实验中,我们使用了Python中的heapq库来实现了堆排序,以加快Prim算法的运行速度。

4.实验结果经过实验,我们得到了图的最小生成树以及对应的权值。

实验数据显示,当图中顶点较少时,Prim算法和Kruskal算法几乎没有明显的差别。

但当图的规模增大时,Prim算法明显比Kruskal算法更快。

5.实验分析从实验结果可以看出,Prim算法和Kruskal算法都可以求解最小生成树,但在不同情况下它们的性能表现并不相同。

Prim算法适用于稠密图,因为它的时间复杂度与顶点的平方成正比;而Kruskal算法适用于稀疏图,因为它的时间复杂度与边的数量成正比。

最小生成树实验报告

最小生成树实验报告

最小生成树实验报告最小生成树(Minimum Spanning Tree,MST)是图论中的一个重要概念,用于在一个连通带权无向图中找到一个子图,使得这个子图是一个树(即无环连通图),并且所有边的权值之和最小。

最小生成树在诸多领域有着广泛的应用,如网络设计、电力传输等。

在本次实验中,我们实现了最小生成树算法,并将其运用到多个实际问题上。

下面将依次介绍算法原理、实现过程、实验结果以及对实验的进一步改进。

1.算法原理Kruskal算法的基本思想是,首先将所有边按照权值从小到大排序,然后从最小的边开始,逐一加入生成树,直到生成树包含了所有的顶点。

在加入一条边时,需要判断这条边将两个顶点连通起来是否会形成环,如果不会则加入生成树。

Prim算法的基本思想是,从一个顶点开始,逐步加入生成树的顶点,每次加入一个顶点时,选择一个离生成树最近的点,并将这个点加入生成树。

通过不断的选择顶点和加入边,最终得到最小生成树。

2.实现过程首先,我们实现了图的数据结构和边的数据结构。

在图的数据结构中,我们定义了图的顶点数和边数,并用邻接矩阵来表示图的连接情况。

边的数据结构包含了两个顶点和边的权值。

其次,我们实现了两种算法。

对于Kruskal算法,我们首先将所有边按照权值从小到大进行排序。

然后,逐个加入边,判断是否形成环。

如果不会形成环,则将该边加入生成树。

最后,我们使用并查集数据结构来判断两个顶点是否连通。

对于Prim算法,我们首先选择一个起点作为生成树的初始顶点,并将其加入生成树。

然后,每次选择一个离生成树最近的顶点,并将其加入生成树,同时更新其他顶点到生成树的距离。

最后,所有顶点都被加入生成树后,得到最小生成树。

3.实验结果我们在实验中选择了不同大小的图进行测试。

经过对比,我们发现Kruskal算法和Prim算法得到的最小生成树结果是一致的,但是Kruskal 算法的时间复杂度要稍高于Prim算法。

具体的结果如下:对于一个边数为10的图,我们得到了如下最小生成树:1-2-4-5-3总权重为12对于一个边数为20的图,我们得到了如下最小生成树:2-1-4-5-3总权重为16对于一个边数为30的图2-1-4-5-6-7-3总权重为22从实验结果来看,无论是规模较小的图还是规模较大的图,我们都能够得到最小生成树,并且所得到的结果是正确的。

数据结构实验报告最小生成树参考模板

数据结构实验报告最小生成树参考模板

HUNAN UNIVERSITY 课程实习报告
题目:最小生成树
学生姓名:
学生学号:
专业班级:
指导老师:
完成日期:
一、需求分析
若要在n个城市之间建设通信网络,只需要架设n-1条线路即可。

如何以最低的经济代价建设这个通信网,是一个网的最小生成树问题
二、概要设计
抽象数据类型
用数组将边的距离及权值进行存储并排序。

算法的基本思想
构造生成树的网一定是无向网。

并设顶点数不超过30个,边权值为小于100的整数。

根据克鲁斯卡尔算法的特点,为便于选择选择权值小的边,存储结构不选用邻接矩阵和邻接表,而是可以用存储边(带权)的数组表示图。

程序的流程
程序由三个模块构成:
(1)从文件中读入图的信息。

(2)利用克鲁斯卡尔算法求网的最小生成树。

(3)以文本形式生成树中各条边以及他们的权值。

三、
四、详细设计
算法的具体步骤
先将用户的输入的顶点和边的数量,根据这些信息构建出图的结构,最后对边的权值进行排序。

输入和输出的格式
输入:
输入顶点和边的个数及顶点之间的权值。

输出:
输出最小生成树的序列。

五、测试结果
六、实验心得
实验的时候不是这个结果啊,可能是哪个环节出了错误,但是思想没有问题的,通过本次实验学会了用C++实现最小生成树。

友情提示:范文可能无法思考和涵盖全面,供参考!最好找专业人士起草或审核后使用,感谢您的下载!。

数据结构 实验8 最小生成树

数据结构 实验8 最小生成树
1、实验目的
(1)复习图的存储方法和图的遍历方法;
(2)进一步掌握图的非线性特点、递归特点和动态特性;
(3)掌握最小生成树的求解算法。
2、实验内容
(1)用Prim算法求最小生成树;
(2)输入网的二维矩阵,输出最小生成树;
3、实验要求
(1)分析算法思想,利用C(C++)语言完成程序设计。
(2)上机调试通过实验程序。
if(g[k][j]<lowcost[j])
{lowcost[j]=g[k][j];
closest[j]=k;
}
printf("\n");
}
}
int adjg(int g[][max]) //建立无向图
{
int n,e,i,j,k,v1,v2,weight;
printf("输入顶点个数,边的条数:");
⑵源代码
#include <stdio.h>
#define inf 9999
#define max 40
void prim(int g[][max],int n) // prim的函数
{
int lowcost[max],closest[max];
int i,j,k,min;
for(i=2;i<=n;i++) // n个顶点,n-1条边
scanf("%d,%d",&n,&e);
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
g[i][j]=inf; //初始化矩阵,全部元素设为无穷大
for(k=1;k<=e;k++)

数据结构实验Prim最小生成树

数据结构实验Prim最小生成树

实验三:Prim 最小生成树(验证性、4学时)一、 实验目的和要求●理解图的遍历●理解构造无向联通图的最小生成树的方法(Prim 算法实现)●能用Prim 算法构造最小生成树出来二、 实验内容和原理(1)实验内容:用Prim 算法构造一颗最小生成树(2) 实验原理:①从网中任一顶点开始,先把该顶点包含在生成树中,此时生成树只有一个顶点。

②找出一个端点在生成树中另一端点在生成树外的所有边,并把权值最小的边连到同它所关联的另一个顶点添加到生成树中;当有两条及以上具有相同最小权值的边可供选择时,任选一条。

③反复执行②,直到所有顶点都包含在生成树时为止。

三、 实验环境硬件:(1)学生用微机(2)多媒体教室或远程教学(3)局域网环境软件:(1)Windows XP 中文操作系统 (2)Turbo C 3.0四、 算法描述及实验步骤1、算法描述为了实现Prim 算法。

需设一个辅助数组closedge 来记录每次选择的权值最小的边。

数组元素closedge[i]对应于序号为i 的顶点v i ,它包含两个域adjvex 和lowcost 。

若v i 已在生成树上,则置closedge[i].lowcost=0;若顶点v i 不在生成树上,用closedge[i].low cost 存放v i 与生成树上的顶点构成的最小代价边的权值,而用closedge[i].adjvex 存放该边所关联的生成树上的另一顶点的序号。

2、算法流程图begin typedef struct ArcCellvoid CreateGraph(MGraph &G) hand !=110 1113、代码(注释)#include <stdio.h>#include <stdlib.h>#include <iostream.h>#define INFINITY INT_MAX tide != G .vexs[k] G .arcs[j][k].adj = weigh; G .arcs[k][j].adj = weigh; j = 0;k = 0;void MiniSpanTree_PRIM(MGraph G ,V erTexType u) j<G .vexnum G .arcs[k][j].adj < close[j].lowcostclose[j].adjvex = G .vexs[k]; close[j].lowcost= G .arcs[k][j].adj;j++ j++j=0i++int LocateV ex(MGraph G , V erTexType u) end int minimum(closedgeclose)#define MAX_VERTEX_NUM 20 //最大顶点数为20//typedef int VRType;typedef int InfoType;typedef char V erTexType;typedef struct ArcCell // 邻接矩阵定义//{VRType adj;InfoType *info; }ArcCell, AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; typedef struct{V erTexType vexs[MAX_VERTEX_NUM];AdjMatrix arcs;int vexnum, arcnum; }MGraph;typedef struct //记录从顶点集U到V-U的代价最小的边的辅助数组定义//{ V erTexType adjvex;VRType lowcost;}closedge[MAX_VERTEX_NUM];void CreateGraph(MGraph &G); //建立无向图//void MiniSpanTree_PRIM(MGraph G, V erTexType u);//用Prim算法从第u个顶点出发构造无向连通网G的最小生成树T//int LocateV ex(MGraph G, V erTexType u);//求顶点在图中的位置//int minimum(closedge close);//最小边的权重//void main( void ){int i, j;MGraph G;cout<<"==================用Prim算法求最小生成树==================="<<endl; CreateGraph(G);//调用CreateGraph(G)建立图//cout<<"程序所建立的图的邻接矩阵如下所示:"<<endl;cout<<"-------------------------------------";cout<<endl<<" ";for(i = 0; i < G.vexnum; i++){cout<<G.vexs[i]<<" ";}cout<<endl;for(i = 0; i < G.vexnum; i++){cout<<G.vexs[i]<<" ";for(j = 0; j < G.vexnum; j++){cout<<G.arcs[i][j].adj;cout<<" ";}cout<<endl;}cout<<"-------------------------------------"<<endl;MiniSpanTree_PRIM(G,'a');}void CreateGraph(MGraph &G)//构造无向连通网G//{int weigh;//weigh变量为图中结点的权重//int i, j = 0, k = 0;char hand, tide;cout<<"请您输入所建图中的结点的个数the number for vexnum:";cin>>G.vexnum;cout<<"请您输入所建图中的各结点间的连接的边数(最大边数为"<<G.vexnum*G.vexnum<<")the number for arcnum:";cin>>G.arcnum;for(i = 0; i < G.vexnum; i++){for(j = 0; j < G.vexnum; j++)G.arcs[i][j].adj = 99; }//图中两个结点不相联,权值定为99//cout<<endl;cout<<"请您输入"<<G.vexnum<<"(char)型的字符作为图中的结点名称:"<<endl;for(i=0; i < G.vexnum; i++){cin>>G.vexs[i];}cout<<endl;cout<<"请您输入"<<G.vexnum<<"(char)型的字符作为图中的结点名称:"<<endl;for(i=0; i < G.arcnum; i++){cout<<i+1<<":";cin>>hand;cin>>tide;cin>>weigh;while (hand != G.vexs[j]){j++;}while (tide != G.vexs[k]){k++;}G.arcs[j][k].adj = weigh;G.arcs[k][j].adj = weigh;j = 0;k = 0;}cout<<endl;}void MiniSpanTree_PRIM(MGraph G,V erTexType u)//用Prim算法从第u个顶点出发构造网G 的最小生成树T,输出它的各条边并算出//{int i, j, k = 0;closedge close;k = LocateV ex ( G, u );for ( j = 0; j < G.vexnum; j++ )//辅助数组初始化//{if (j != k){close[j].adjvex = G.vexs[k];close[j].lowcost = G.arcs[k][j].adj;}}close[j].lowcost = 99;close[j].adjvex = '\0';close[k].lowcost = 0;close[k].adjvex = u;cout<<"用Prim算法实现的程序求得的最小生成树如下所示:"<<endl;for (i = 1; i < G.vexnum; i++)//选择其余G.vexnum-1个顶点//{k = minimum(close); //求出T的下一个结点:第k个顶点//cout<<close[k].adjvex; //输出生成树的边//cout<<"---->";cout<<G.vexs[k]<<" ";cout<<close[k].lowcost<<endl;close[k].lowcost = 0; //第k顶点并入U集//for (j=0; j<G.vexnum; j++){if (G.arcs[k][j].adj < close[j].lowcost)//新顶点并入U集后重新选择最小边//{close[j].adjvex = G.vexs[k];close[j].lowcost = G.arcs[k][j].adj;} } } }int LocateV ex(MGraph G, V erTexType u)//求顶点在图中的位置//{int k = 0;while(G.vexs[k++] == u)return k-1;return 0;}//若G中存在顶点u则返回该顶点在图中的位置,否则返回-1//int minimum(closedge close)//最小边的权重//{int j1=0, client = 99, j2;while(close[j1].adjvex != '\0'){if (client > close[j1].lowcost && close[j1].lowcost != 0){client = close[j1].lowcost;j2 = j1;}j1++;}return j2;}五、调试过程出错原因:语句“InfoType ->info;”出错,只要把“InfoType ->info;”改为即“InfoType *info;”即可。

数据结构-最小生成树实验报告

数据结构-最小生成树实验报告

#include<stdio.h>#include<stdlib.h>#define MAXLEAF 100#define INF 100000#define EDGENUMBER MAXLEAF*MAXLEAF/2typedef int EdgeType;typedef int VertexType;typedef struct{EdgeType val[MAXLEAF][MAXLEAF];VertexType ves[MAXLEAF];int v;int e;}MGraph;typedef struct{int vex1,vex2;int w;}kedge;void creat_MGraph(MGraph *M){int i,j,k;int w;printf("请输入图的顶点个数及边数:\n");scanf("%d%d",&(M->v),&(M->e));printf("请依次填充顶点信息:\n");for(i=0;i<M->v;i++)scanf("%d",&(M->ves[i]));for(i=0;i<M->v;i++)for(j=0;j<M->v;j++)if(i==j) M->val[i][j]=0;else M->val[i][j]=INF;printf("请依次输入图的边两个顶点顶点的权值:(格式:a b c)\n");for(k=0;k<M->e;k++){scanf("%d%d%d",&i,&j,&w);M->val[i-1][j-1]=w;M->val[j-1][i-1]=w;}}VertexType kruskal(MGraph M){int tag[MAXLEAF];kedge Ke[EDGENUMBER];int i,j;VertexType length=0;int n=0;for(i=0;i<M.v;i++) tag[i]=i;for(i=0;i<M.v;i++)for(j=i+1;j<M.v;j++)if(M.val[i][j]!=INF){Ke[n].vex1=i;Ke[n].vex2=j;Ke[n++].w=M.val[i][j];}kedge temp;for(i=0;i<n-1;i++)for(j=0;j<n-i-1;j++)if(Ke[j].w>Ke[j+1].w){temp=Ke[j+1];Ke[j+1]=Ke[j];Ke[j]=temp;}for(i=0;i<n;i++){int first,second;first = tag[Ke[i].vex1];second = tag[Ke[i].vex2];if(first!=second){length+=Ke[i].w;printf("%d->%d: %d\n",Ke[i].vex1,Ke[i].vex2,Ke[i].w);tag[Ke[i].vex2]=first;for(j=0;j<M.v;j++){if(second==tag[j])tag[j]=first;}}}return length;}int main(){MGraph M;int len;creat_MGraph(&M);printf("最小生成树:\n");len=kruskal(M);printf("最小成本:%d",len);return 0;}。

最小生成树实验报告

最小生成树实验报告

一、实验目的1. 通过上机程序,进一步加深对最小生成树的理解。

2. 掌握Kruskal算法。

3. 学会用程序解决离散数学中的问题。

4. 增强我们编写程序的能力。

二、实验内容求带权无向联通平面图的最小生成树三、实验环境我的实验依旧是在实验环境下完成的,而所设计的程序也在这个环境下通过了编译,运行和测试。

四、实验原理和实现过程利用Kruskal算法求最小生成树,原理如下:1.选取最小权边e1,置边数j 1.2.i=n-1结束,否则转c。

3.设已经选择的边为e1,e2,......,ei,在G中选取不同于e1,e2, (i)边,使{e1,e2,……,ei,ei+1}中无回路且ei+1是满足此条件的最小边。

4.i i+1,转b。

根据这个,还有以下思路:由G生成的最小生成树T所包含的边的集合1.按非降序权重将E中的边排序2.建立n个单元素集(每个顶点一个)3.最小生成树的边集合T初始为空4 .while |T|<n-15. 令e(x,y)为E中的下一条边6. if包含x的集合不是与包含y的集合不是同一个集合 then7. 将e(x,y)加入到T8. 将包含x的集合和包含y的集合合并9. end ifwhile五、实验源代码及分析#include<>struct Edge{int from, to, weight; rom); o);if(x!=y) rom, edge[k].to, edge[k].weight); rom, &edge[i].to, &edge[i].weight); eight>edge[j].weight){temp=edge[i];edge[i]=edge[j];edge[j]=temp;}printf("The minimum spanning tree is:\n");Kruskal(); //调用Kruskal算法return 0;}其中运用seek函数找出当前端点所在集合编号。

最小生成树数据结构实验报告【范本模板】

最小生成树数据结构实验报告【范本模板】

数据结构实验报告名称:最小生成树班级:122姓名:*****学号:***********指导老师:********一、设计目的与任务1。

1课程设计目的本课程设计的目的是了解并掌握数据结构与算法的设计方法,具备初步的独立分析和设计能力;初步掌握软件开发过程的问题分析、系统设计、程序编码、测试等基本方法和技能;提高综合运用所学的理论知识和方法独立分析和解决问题的能力;训练用系统的观点和软件开发一般规范进行软件开发。

1。

2课程设计的任务问题描述:已知一个无向连通网表示n个城市以及城市间可能设置的通信线路,其中网的顶点表示城市,边表示两个城市之间的线路,赋于边上的权值表示相应的代价.对于n个点的连通网能建立许多不同的生成树,每一棵生成树都可以是一个通信网。

我们要选择一棵生成树,使总的耗费最小。

二、设计方案2。

1需求分析(1)建立一个图,其存储方式可以采用邻接矩阵形式或者邻接表;(2)利用普利姆算法或者克鲁斯卡尔算法求出网的最小生成树;(3)输入各城市的数目以及各个城市之间的距离。

将城市之间的距离当做网中各点之间的权值。

按顺序输出生成树中各条边以及它们的权值。

2.2数据结构分析构造最小生成树的方法:最初生成树为空,即没有一个结点和一条边,首先选择一个顶点作为生成树的根,然后每次从不在生成树中的边中选择一条权值尽可能小的边,为了保证加入到生成树中的边不会造成回路,与该边邻接的两个顶点必须一个已经在生成树中,一个则不在生成树中,若网中有n个顶点(这里考虑的网是一个连通无向图),则按这种条件选择n—1边就可以得到这个网的最小生成树了。

详细的过程可以描述为:设置2个集合,U集合中的元素是在生成树中的结点,V—U集合中的元素是不在生成树中的顶点。

首先选择一个作为生成树根结点的顶点,并将它放入U集合,然后在那些一端顶点在U集合中,而另一端顶点在V-U集合中的边中找一条权最小的边,并把这条边和那个不在U集合中的顶点加入到生成树中,即输出这条边,然后将其顶点添加到U集合中,重复这个操作n-1次。

数据结构实验报告十二—最小生成树问题

数据结构实验报告十二—最小生成树问题

问题描述:若要在n个城市之间建设通信网络,只需要架设n-1条线路即可。

如何以最低的经济代价建设这个通信网,是一个网的最小生成树问题。

一、需求分析:需定义结构体数组,根据权值逐一选择边。

二、概要设计:抽象数据类型:需定义结构体数组,存储每条边的起点,终点,权值。

算法的基本思想:1、图的信息的读取:定义结构体数组,存储每条边的起点,终点,权值。

2、对每条边在数组中的位置处理:选边需从最小的开始,故按边的权值从小到大进行排序。

3、边的选取:从最小的边的开始,若边的两端点不属于同一集合,则选取该边。

并将该边的两个顶点所在的两个集合合并成为一个。

因为有n个顶点,故只需选取n-1条边。

程序的流程程序由三个模块组成:输入模块:读入图的信息(顶点和边,用结构体数组进行存储)。

处理模块:Kruskal算法。

输出模块:将结果输出。

三、详细设计算法的具体步骤:struct G{int fromvex;int endvex;int weight;}GE[100],cur[100];void swap(G* GE,int i,int j){ //交换函数int temp=GE[i].fromvex;GE[i].fromvex=GE[j].fromvex;GE[j].fromvex=temp;temp=GE[i].endvex;GE[i].endvex=GE[j].endvex;GE[j].endvex=temp;temp=GE[i].weight;GE[i].weight=GE[j].weight;GE[j].weight=temp;}void Kruskal(int n){int i,j,k=0,pos=-1,m1,m2;bool** s=new bool *[n];//定义一个二维数组,用来判断是否为同一类for(i=0;i<n;i++)s[i]=new bool[n];for(i=0;i<n;i++){for(j=0;j<n;j++){if(i==j)s[i][j]=true; //初始化数组elses[i][j]=false;}}while(k<n-1){for(i=0;i<n;i++){if(s[i][GE[k].fromvex]==1)m1=i;if(s[i][GE[k].endvex]==1)m2=i;}if(m1!=m2){//判断是否为同一类,如果为同一类(该类中所有的点到起点和终//点的边在s数组中赋为1),cur[++pos].fromvex=GE[k].fromvex;cur[pos].endvex=GE[k].endvex;cur[pos].weight=GE[k].weight;for(i=0;i<n;i++){if(s[m1][i] || s[m2][i])//把该点添加到该类,并和并两个类s[m1][i]=1;elses[m1][i]=0;s[m2][i]=0;}}k++;}for(i=0;i<n;i++){delete []s[i];}}int main(){int i,j;int numVertex,numEdge;cout<<"请输入点的个数和边的条数:"<<endl;cin>>numVertex>>numEdge;cout<<"请输入边的起始位置和边的权值:"<<endl;for(i=0;i<numEdge;i++)cin>>GE[i].fromvex>>GE[i].endvex>>GE[i].weight;for(i=0;i<numEdge;i++)for(j=i;j<numEdge;j++){if(GE[j].weight<GE[i].weight)//将边的权值按从小到大排列swap(GE,i,j);}Kruskal(numEdge);for(i=0;i<numVertex-1;i++)cout<<cur[i].fromvex<<"->"<<cur[i].endvex<<":"<<cur[i].weight<<endl; system("pause");return 0;}四、调试分析:将选边的过程输出来检验算法的正确性。

实验5最小生成树算法的设计与实现(报告)

实验5最小生成树算法的设计与实现(报告)

实验5 最小生成树算法的设计与实现一、实验目的1、根据算法设计需要, 掌握连通图的灵活表示方法;2、掌握最小生成树算法,如Prim、Kruskal算法;3、基本掌握贪心算法的一般设计方法;4、进一步掌握集合的表示与操作算法的应用。

二、实验内容1、认真阅读算法设计教材和数据结构教材内容, 熟习连通图的不同表示方法和最小生成树算法;2、设计Kruskal算法实验程序。

有n个城市可以用(n-1)条路将它们连通,求最小总路程的和。

设计测试问题,修改并调试程序, 输出最小生成树的各条边, 直至正确为止。

三、Kruskal算法的原理方法边权排序:1 3 14 6 23 6 41 4 52 3 53 4 52 5 61 2 63 5 65 6 61. 初始化时:属于最小生成树的顶点U={}不属于最小生成树的顶点V={1,2,3,4,5,6}2. 根据边权排序,选出还没有连接并且权最小的边(1 3 1),属于最小生成树的顶点U={1,3},不属于最小生成树的顶点V={2,4,5,6}3. 根据边权排序,选出还没有连接并且权最小的边(4 6 2),属于最小生成树的顶点U={{1,3},{4,6}}(还没有合在一起,有两颗子树),不属于最小生成树的顶点V={2,5}4. 根据边权排序,选出还没有连接并且权最小的边(3 6 4),属于最小生成树的顶点U={1,3,4,6}(合在一起),不属于最小生成树的顶点V={2,5}5. 根据边权排序,选出还没有连接并且权最小的边(3 6 4),属于最小生成树的顶点U={1,2,3,4,6},,不属于最小生成树的顶点V={5}6. 根据边权排序,选出还没有连接并且权最小的边(3 6 4),属于最小生成树的顶点U={1,2,3,4,5,6}此时,最小生成树已完成四、实验程序的功能模块功能模块:bool cmp(Edge a,Edge b); //定义比较方法x);//在并查集森林中找到x的祖先int g etfa(intint s ame(int x,int y); //判断祖先是否是同一个,即是否联通 void merge(int x,int y); //合并子树,即联通两子树sort(e+1,e+m+1,cmp); //对边按边权进行升序排序详细代码:#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#define M AXN_E 100000#define M AXN_V 100000using namespace std;struct Edge{int f m,to,dist;//边的起始顶点,边的到达顶点,边权}e[MAXN_E];int f a[MAXN_V],n,m; //顶点数组,顶点总数,边总数 //定义比较,只是边权比较bool cmp(Edge a,Edge b){return a.dist < b.dist;}//查找x的祖先是在并查集森林中找到x的祖先x){//getfaint g etfa(intreturn fa[x];if(fa[x]==x)else r eturn fa[x] = getfa(fa[x]);}//判断祖先是否是同一个,即是否联通int s ame(int x,int y){return getfa(x)==getfa(y);}//合并两棵树void merge(int x,int y){int f ax=getfa(x),fay=getfa(y);fa[fax]=fay;}int m ain(){int i;cout<<"请输入顶点数目和边数目:"<<endl;cin>>n>>m;//n为点数,m为边数//输出顶点信息cout<<"各个顶点值依次为:"<<endl;for(i=0;i<n;i++){fa[i]=i;if(i!=0)cout<<fa[i]<<" ";}cout<<endl;cout<<"请输入边的信息(例子:1 4 5 从顶点1到顶点4的边权为5)"<<endl;for(i=1;i<=m;i++)用边集数组存放边,方便排序和调用 cin>>e[i].fm>>e[i].to>>e[i].dist;//sort(e+1,e+m+1,cmp); //对边按边权进行升序排序表示目前的点共存在于多少个集合中,初始情况是每 int r st=n,ans=0;//rst个点都在不同的集合中for(i=1;i<=m && rst>1;i++){int x=e[i].fm,y=e[i].to;函数是查询两个点是否在同一集合中 if(same(x,y))continue;//sameelse{函数用来将两个点合并到同一集合中 merge(x,y);//mergerst--;//每次将两个不同集合中的点合并,都将使rst值减1这条边是最小生成树中的边,将答案加上边权 ans+=e[i].dist;//}}cout<<ans;return 0;}五、测试数据和相应的最小生成树Input:6 101 2 61 3 11 4 52 3 52 5 63 4 53 5 63 6 44 6 25 6 6Putout:18生成树为:七、思考题1、微软面试题一个大院子里住了50户人家,每家都养了一条狗,有一天他们接到通知说院子里有狗生病了,并要求所有主人在发现自己家狗生病的当天就要把狗枪杀掉。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实验九图的最小生成树算法的实现实验预备知识:1.理解图最小生成树的意义和相应算法。

2.掌握带权图的存储结构。

一、实验目的1.使学生熟悉最小生成树的算法实现。

2.掌握带权图的存储结构和处理方法。

二、实验环境⒈硬件:每个学生需配备计算机一台。

操作系统:DOS或Windows;⒉软件:DOS或Windows操作系统+Turbo C;三、实验要求1.能够独立完成带权图的存储和最小生成树的生成四、实验内容1.在自己的U盘的“姓名+学号”文件夹中创建“实验9”文件夹,本次实验的所有程序和数据都要求存储到本文件夹中。

2.现在某电信公司要对如下图的几个城市之间进行光纤连接布线,请用合适的存储结构将下图存储到计算机中方便进行处理。

3.现在公司想以最小的代价将所有城市连通,方便所有城市间通信,请用普里姆算法和克鲁斯卡尔算法实现本图的最小生成树#include <stdio.h>#include <stdlib.h>#define INF 50typedef struct ArcNode{int adjvex; //该弧所指向的顶点位置struct ArcNode *nextarc; //下一个临接点int weight; //弧的权重}ArcNode; //表结点typedef struct VNode{char data; //顶点信息ArcNode *firstarc; //指向下一个结点}VNode,AdjList[6];typedef struct{AdjList LH; //创建头结点数组int vexnum; //图的点的个数int arcnum; //图的边的个数}Graph;typedef struct{char nextvex;int lowcost;int know;}Auxiliary_array; //辅助数组结构体void main (void){void buildtu (Graph*);void printgraph(Graph*);void prim( Graph *G, char u);char u;Graph UDG;Graph *G = &UDG;buildtu(G);printgraph(G); //打印图printf("请输入起始顶点:\n");while(getchar()!='\n');u = getchar();prim(G ,u);}void buildtu (Graph *G) { //建图int search(Graph *G,char a);int i,n1,n2,w;char a,b;ArcNode *p, *q;printf("请输入顶点个数和边的条数:\n");scanf("%d %d",&G->vexnum,&G->arcnum);printf("请输入顶点信息\n");for (i = 0; i < G->vexnum; ++i){while (getchar()!='\n');scanf("%c",&G->LH[i].data);G->LH[i].firstarc = NULL;}printf("请输入有关系的结点和该边的权重:\n");for(i=0;i<G->arcnum;++i){while (getchar()!='\n');scanf("%c %c %d",&a,&b,&w);n1=search(G,a);n2=search(G,b);p=G->LH[n1].firstarc;if(p == NULL){p=G->LH[n1].firstarc=(ArcNode *) malloc (sizeof(ArcNode));}else{while( p->nextarc !=NULL ){p=p->nextarc;}p=p->nextarc=(ArcNode *) malloc (sizeof(ArcNode));}q=G->LH[n2].firstarc;if(q == NULL){q=G->LH[n2].firstarc=(ArcNode *) malloc (sizeof(ArcNode));}else{while( q->nextarc !=NULL ){q=q->nextarc;}q=q->nextarc=(ArcNode *) malloc (sizeof(ArcNode));}p->adjvex=n2;p->weight=w;p->nextarc=NULL;q->adjvex=n1;q->weight=w;q->nextarc=NULL;}}int search (Graph *G,char a){ //确定顶点a在头结点数组中的位置int i;for(i=0;i<G->vexnum;++i){if(G->LH[i].data==a){return i;}}}void printgraph(Graph *G){ //打印图int i;ArcNode *p;for (i=0 ; i < G->vexnum; ++i){p=G->LH[i].firstarc;printf("data:%c \t",G->LH[i].data);while(p!=NULL){printf("firstarc->adjvex=%d",p->adjvex);p=p->nextarc;}printf("\n");}}void prim( Graph *G, char u){//用prim算法实现最小生成树int search (Graph *G,char a);int minimize(Graph *G, Auxiliary_array[]);void printtable(Auxiliary_array[]);Auxiliary_array A[6]; //创建辅助数组int i,j,seat;int location;ArcNode *p ;for (i = 0; i < G->vexnum; ++i) {A[i].nextvex = '0';A[i].know= 0;A[i].lowcost = INF;}location = search(G ,u);//确定u元素在头结点数组中的位置for (p=G->LH[location].firstarc ; p != NULL; p=p->nextarc ){i = p->adjvex;A[i].nextvex = G->LH[location].data;A[i].lowcost = p->weight;A[i].know= 0;}A[location].know = 1;A[location].lowcost = 0;A[location].nextvex = '0';for(j=0;j<G->vexnum-1;++j){seat = minimize( G,A );printf("select min: %d\n", seat);A[seat].know = 1;p=G->LH[seat].firstarc;for (p; p != NULL; p=p->nextarc){i=p->adjvex;if(A[i].know == 0 && p->weight < A[i].lowcost){A[i].nextvex = G->LH[seat].data;A[i].lowcost = p->weight;}}}printtable(A); //打印辅助数组中的信息for (j = 0; j < G->vexnum; ++j)if (j != location)printf("%c<---->%c\n",A[j].nextvex,G->LH[j].data);}int minimize(Graph *G, Auxiliary_array A[]){//取出辅助数组中权值最小的顶点所在的位置int i,place,num;num = INF;for (i = 0; i < G->vexnum; ++i){if(A[i].know == 0 && num >= A[i].lowcost){num = A[i].lowcost;place = i;}}return place;}void printtable(Auxiliary_array A[]) {//打印辅助数组int i;for (i = 0; i < 6; i++) {printf("modifier:%c lowcost:%d known:%d\n", A[i].nextvex, A[i].lowcost, A[i].know);}}实验总结:通过该实验,我深刻明白到了自己对循环的能力不足,书写代码的逻辑性也不够强,相信在以后的学习中能加强这方面的学习,争取在以后的学习中解决这两个方面的问题。

相关文档
最新文档