数据结构课程设计Word格式文档下载.docx

上传人:b****6 文档编号:19926413 上传时间:2023-01-12 格式:DOCX 页数:14 大小:33.41KB
下载 相关 举报
数据结构课程设计Word格式文档下载.docx_第1页
第1页 / 共14页
数据结构课程设计Word格式文档下载.docx_第2页
第2页 / 共14页
数据结构课程设计Word格式文档下载.docx_第3页
第3页 / 共14页
数据结构课程设计Word格式文档下载.docx_第4页
第4页 / 共14页
数据结构课程设计Word格式文档下载.docx_第5页
第5页 / 共14页
点击查看更多>>
下载资源
资源描述

数据结构课程设计Word格式文档下载.docx

《数据结构课程设计Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《数据结构课程设计Word格式文档下载.docx(14页珍藏版)》请在冰豆网上搜索。

数据结构课程设计Word格式文档下载.docx

一、分析题目要求

1、在这个课程设计中,我做的是并查集。

主要实现以下的功能:

1)初始化

2)合并结合

3)查找节点所在集合

4)相关应用

初始化:

把每个点所在集合初始化为其自身。

通常来说,这个步骤在每次使用该数据结构时只需要执行一次,无论何种实现方式时间复杂度均为O(N)。

查找:

查找元素所在的集合,即根节点。

合并:

将两个元素所在的集合合并为一个集合。

通常来说,合并之前,应先判断两个元素是否属于同一集合,这可用上面的“查找”操作实现。

为了在这个程序实现中更好地表现出相关功能,我用了一个具体的例子,也即是判断多个城市之间的并查集,并求出不同城市的距离长短。

2、各个函数命名,包含的参数,返回值类型

intmenu()//函数主菜单

voidxin_input()//第二级菜单

boolcmp(nodep1,nodep2)

//并查集

voidset(intx)//初始化

intfind(intx)//寻找数据的共同祖先

voidUnion(intx,inty)//合并函数

//算法

voidKruskal()//Kruskal算法

intprim()//prim算法

voidShortestPath_DIJ(intx,inty)//Dijkstra算法

voidShortestPath_FLOYD()//Floyd算法

voidshuru()//接收函数(接收输入的数据)

voidchaxun()//查询函数

//功能函数

voidchaxun_func()

voidjudge()

intmain()//主函数

3、程序的运行

二、解题思路

1、单链表实现

一个节点对应一座城市,在同一个集合中的节点串成一条链表就得到了单链表的实现。

在集合中我们以单链表的第一个节点作为集合的代表元。

于是每个节点x(x也是城市的编号)应包含这些信息:

指向代表元即表首的指针head[x],指向表尾的指针tail[x],下一个节点的指针next[x]。

2、两大优化

第一个优化是启发式合并。

在优化单链表时,我们将较短的表链到较长的表尾,在这里我们可以用同样的方法,将深度较小的树指到深度较大的树的根上。

这样可以防止树的退化,最坏情况不会出现。

Find-Set(x)的时间复杂度为O(logN),PROBLEM-Relations时间复杂度为O(N+logN(M+Q))。

SUB-Link(a,b)作相应改动

第二个优化是路径压缩。

它非常简单而有效。

如图所示,在Find-Set

(1)时,我们“顺便”将节点1,2,3的父节点全改为节点4,以后再调用-Find-Set

(1)时就只需O

(1)的时间。

 

三、调试分析

由于此程序实现的功能较为简单,故在调试过程中也没遇到很大的问题。

主要的问题在于着手写代码的时候,由于不熟悉及很多算法未接触过,故陷入了无从下手的境地。

但最后通过搜索大量的资料终于解决。

期间用到的测试数据是多组邻接矩阵,没有发现bug;

对于算法的不足之处,主要是时间复杂度过大,代码未能很好优化,另外对于改进的设想,也就是前面提到的两大优化,但由于自己未能实现,故只好作罢了。

所以,此次最大的感受就是自己的知识基础很薄弱,而且对于很多思维性和逻辑性要求很高的东西自己难以理解。

所以自己深知要加强这方面的锻炼。

更为自己过去一学期没能好好掌握的知识而感到痛心,有机会一定要补回来吧。

四、附录

带注释的源程序。

#include<

stdio.h>

string.h>

iostream>

algorithm>

#include<

windows.h>

usingnamespacestd;

intn=0;

inta[100][100];

intmenu()

{

intm;

printf("

并查集\n"

);

________________________________\n\n"

1输入城市之间的信息\n"

2判断是否能构成一个并查集\n"

3查询信息\n"

4退出\n"

请输入所选功能1--4\n"

scanf("

%d"

&

m);

returnm;

}

voidxin_input()

system("

cls"

1遍历所有城市的并查集\n"

2查询两个城市之间的距离\n"

3退出\n"

//以下为克鲁斯卡尔算法

typedefstructnode//构造一个结构体,两个城市可以看成起点和终点,之间的路道可以看成一个边

intst;

//起点

inted;

//终点

intdis;

//距离

}node;

nodep[1000];

intpre[1000],rank[1000];

returnp1.dis<

p2.dis;

//下面三个函数是并查集,其作用是检验当一条边添加进去,是否会产生回路

voidset(intx)

pre[x]=x;

//初始化

rank[x]=0;

intfind(intx)//找到这个点的祖先

if(x!

=pre[x])

pre[x]=find(pre[x]);

returnpre[x];

voidUnion(intx,inty)//将这两个添加到一个集合里去

x=find(x);

y=find(y);

if(rank[x]>

=rank[y])

pre[y]=x;

rank[x]++;

else

voidKruskal()//

intans=0,i,j,k=0;

for(i=1;

i<

=n;

i++)

set(i);

for(j=i+1;

j<

j++)

{

p[++k].st=i;

p[k].ed=j;

p[k].dis=a[i][j];

//先把所有城市之间的路段看成一个边

}

sort(p+1,p+k+1,cmp);

//把所有的边按从小到大进行排序

intcount=0;

=k;

if(find(p[i].st)!

=find(p[i].ed))//如果这两点连接在一起不构成一个回路,则执行下面操作

第%d条路段为:

%d--%d,权值为%d\n"

++count,p[i].st,p[i].ed,p[i].dis);

//将这条边的起点、终点打印出来

ans+=p[i].dis;

//说明这条路段要用

Union(p[i].st,p[i].ed);

遍历所有城市的最短路程为:

%d\n"

ans);

//最短遍历的路程

//printf("

________________________________\n"

//普里姆算法

intprim()

intclose[100],low[100],i,j,ans=0;

//close[j]表示离j最近的顶点,low[j]表示离j最短的距离

booluse[100];

use[1]=1;

for(i=2;

low[i]=a[1][i];

//初始化

close[i]=1;

use[i]=0;

n;

intmin=100000000,k=0;

for(j=2;

if(use[j]==0&

&

min>

low[j])//找到最小的low[]值,并记录

min=low[j];

k=j;

//printf("

%d%d\n"

close[k],k);

if(use[j]==0&

low[j]>

a[k][j])

low[j]=a[k][j];

//修改low[]值和close[]值

close[j]=k;

ans+=a[close[k]][k];

returnans;

//求最短路径-单源点到其余点的最短路径(Dijkstra算法)

voidShortestPath_DIJ(intx,inty)//X指单源点,y指目标点

inti,d[100],j;

use[i]=0;

d[i]=a[x][i];

use[x]=1;

//这个点肯定用过

d[x]=0;

i++)//执行n-1次操作

intmin=100000000,v;

for(j=1;

d[j])//找出最短距离的

min=d[j];

v=j;

use[v]=1;

d[j]>

min+a[v][j])//修改d[]的值

d[j]=min+a[v][j];

%d城市到城市%d的最短距离为:

x,y,d[y]);

//求每一对顶点之间的最短路径(Floyd算法)

intb[100][100];

voidShortestPath_FLOYD()//这个算法耗时多(n^3),不过容易理解

inti,j,k;

b[i][j]=a[i][j];

//先b[][]进行保存,避免a[][]的值发生变化

for(k=1;

k<

k++)

if(b[i][j]>

b[i][k]+b[k][j])

b[i][j]=b[i][k]+b[k][j];

while

(1)

intst,ed;

请输入两个城市的编号:

\n"

//对此进行多次操作

%d%d"

st,&

ed);

%d城市到%d城市的最短距离为:

st,ed,b[st][ed]);

charstr[100];

是否要继续?

yesorno\n"

%s"

str);

if(strcmp(str,"

no"

)==0)

{//printf("

break;

voidshuru()//输入城市信息

inti,j;

if(n!

=0)

是否要确定输入新的城市之间的信息?

yesorno?

return;

请输入城市的个数:

n);

输入%d个城市的邻接矩阵:

n);

a[i][j]);

voidchaxun()//一个查徇两个城市最短径的操作

intt1,t2;

输入第一个城市的编号:

t1);

输入第二个城市的编号:

t2);

ShortestPath_DIJ(t1,t2);

//调用

if(n==0)

这里没有城市之间的信息\n"

return;

xin_input();

请选择以上功能:

1-3\n"

intm1;

m1);

if(m1==1)

Kruskal();

elseif(m1==2)

chaxun();

//else

//break;

intans;

ans=prim();

if(ans>

=100000000)

不能构成并查集\n"

\n\n\n\n能构成并查集!

\n\n\n\n\n"

intmain()

switch(menu())

case1:

shuru();

case2:

judge();

case3:

chaxun_func();

case4:

gotoloop;

loop:

;

return0;

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 外语学习 > 英语学习

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1