数据结构课程设计哈希表最小代价生成树.docx

上传人:b****5 文档编号:3390010 上传时间:2022-11-22 格式:DOCX 页数:20 大小:454.21KB
下载 相关 举报
数据结构课程设计哈希表最小代价生成树.docx_第1页
第1页 / 共20页
数据结构课程设计哈希表最小代价生成树.docx_第2页
第2页 / 共20页
数据结构课程设计哈希表最小代价生成树.docx_第3页
第3页 / 共20页
数据结构课程设计哈希表最小代价生成树.docx_第4页
第4页 / 共20页
数据结构课程设计哈希表最小代价生成树.docx_第5页
第5页 / 共20页
点击查看更多>>
下载资源
资源描述

数据结构课程设计哈希表最小代价生成树.docx

《数据结构课程设计哈希表最小代价生成树.docx》由会员分享,可在线阅读,更多相关《数据结构课程设计哈希表最小代价生成树.docx(20页珍藏版)》请在冰豆网上搜索。

数据结构课程设计哈希表最小代价生成树.docx

数据结构课程设计哈希表最小代价生成树

 

数据结构课程设计报告

 

学院:

班级:

姓名:

学号:

设计题目:

(1)哈希表查找的设计

(2)连通网的最小代价生成树

设计时间:

2014年1月2日至1月7日

(一)

课题三哈希表查找的设计

一、问题分析和任务定义

设哈希表长为20,用除留余数法构造一个哈希函数,以开放定址法中的线性探测再散列法作为解决冲突的方法,编程实现哈希表查找、插入和建立算法。

二、软件设计

(1)程序框图

开始→构造哈希表→输入数据元素→求得哈希地址→装入哈希表→查找元素→插入元素→结束

(2)子函数

1)初始化哈希表

动态分配存储空间

2)求得哈希地址

除留余数法

3)冲突处理

线性探测再散列法

4)输入元素

输入元素个数→循环体输入元素→考虑冲突处理→依次存入哈希地址

5)打印哈希表

6)查找元素

直接去哈希地址比较查找→考虑冲突处理

7)插入元素

查找元素→考虑冲突次数是否过多→插入哈希表

(3)结构体

1)哈希表结构体

装有数据元素的地址;现有数据个数;哈希表长

三、编码实现

源代码如下:

#include

#include

#defineStatusint

#defineElemTypeint

#defineKeyTypeint

#defineNULLKEY0

#defineEQ(x,y)x==y

#defineSUCCESS1

#defineUNSUCCESS0

#defineDUPLICATE-1

#defineOK1

#defineMAXHSIZE20

#defineOVERFLOW-2

#defineNULL0

inthashsize[]={20};

 

typedefstruct

{

ElemType*elem;

intcount;

intsizeindex;

}HashTable;

 

StatusInitHashTable(HashTable*H)

{

H->elem=(int*)malloc(hashsize[0]*sizeof(ElemType));

if(!

H->elem)exit(OVERFLOW);

H->count=0;

H->sizeindex=hashsize[0];

for(inti=0;i

H->elem[i]=0;

returnOK;

}

StatusHash(ElemTypee)//求得哈希地址

{

ElemTypei;

i=e%MAXHSIZE;

returni-1;

}

Statuscollision(ElemType*p,constElemType*c)

{

//(*p)+=*c;

*p=(*p)+(*c);

if(*p>MAXHSIZE)

exit(OVERFLOW);

elsereturnSUCCESS;

}

StatusInputData(HashTable*H,int*p,int*c)

{

inti,n,t1,t2,t3;

int*pa;

printf("请输入元素个数:

");

//n=getchar();

scanf("%d",&n);

pa=(int*)malloc(n*sizeof(int));

printf("开始输入数据:

\n");

for(i=0;i

{

//scanf("%d",&t);

scanf("%d",(pa+i));

//printf("%d",*(pa+i));

*p=Hash(*(pa+i));

//printf("%d",*(pa+i));

//t1=(H->elem[*p]!

=NULLKEY);

//t2=!

(EQ(*(pa+i),H->elem[*p]));

//printf("%d",*(pa+i));

while((H->elem[*p]!

=NULLKEY)&&!

(EQ(*(pa+i),H->elem[*p])))

{

t3=++(*c);

collision(p,c);

}

H->elem[*p]=*(pa+i);

H->count++;

}

return0;

}

StatusPrintHash(HashTable*H)

{

inti;

printf("当前哈希表如下:

\n");

for(i=0;i>1;++i)

{

printf("%5d",H->elem[i]);

}

putchar('\n');

for(;i

{

printf("%5d",H->elem[i]);

}

putchar('\n');

printf("按任意键继续\n");

getchar();

getchar();

//Menu();

return0;

}

StatusSearchHash(HashTableH,KeyTypeK,int*p,int*c)

{

intt;

*p=Hash(K);

while(H.elem[*p]!

=NULLKEY&&!

(EQ(K,H.elem[*p])))

{

t=++(*c);

collision(p,&t);

}

if(EQ(K,H.elem[*p]))

returnSUCCESS;

elsereturnUNSUCCESS;

}

 

StatusInsertHash(HashTable*H,ElemTypee)

{

intc=0;

intp;

p=Hash(e);

//printf("%d",e);

if(SearchHash(*H,e,&p,&c))

returnDUPLICATE;

elseif(csizeindex/2)

{

H->elem[p]=e;

++H->count;

returnOK;

}

else

{

returnUNSUCCESS;

}

}

StatusRecreateHashTable(HashTable*H)

{

printf("你需要重新构造哈希表\n");

return0;

}

 

voidmain()

{

HashTableHH;

intpp=0,cc=0;

intt=0,key=0,*p=&pp,*c=&cc;

HashTable*H=&HH;

InitHashTable(H);//初始化哈希表,分配内存

InputData(H,p,c);//构造哈希表,输入元素数据

PrintHash(H);//打印哈希表

printf("请输入查找元素:

");//开始查找

scanf("%d",&key);

t=SearchHash(*H,key,p,c);

if(t)

{

printf("查找成功!

\n");

PrintHash(H);

}

elseprintf("哈希表中无此元素\n");

printf("请输入要插入的元素:

");//开始插入

scanf("%d",&key);

t=InsertHash(H,key);

if(t)

{

printf("插入成功!

\n");

PrintHash(H);

}

elseRecreateHashTable(H);

}

四、软件测试

(1)编译环境为MicrosoftVisualStudio2010,运行哈希表.exe,

(2)输入元素个数10

(3)输入数据3,5,8,43,54,21,8,10,9,17,得到哈希表

(4)输入查找元素5,提示查找成功,说明此哈希表含有元素5

(5)若输入查找元素23,则提示哈希表中无此元素

 

(5)插入元素23,提示插入成功,并显示当前哈希表

(6)结论:

程序顺利完成了使用除留余数法构建哈希表,使用线性探测再散列处理冲突,查找元素和插入元素的功能,达到了预期目的。

(二)

课题四连通网的最小代价生成树

一、问题分析和任务定义

如下图要在n个城市之间建立通讯联络网,则连通n个城市只需要修建n-1条线路,编程实现在最节省经费的前提下建立这个通讯网。

图2

图1

将图1等效为图2进行分析。

如图2,这是一个含有6个顶点10条边的连通网,圆圈内的数字为顶点信息,边上的数字为权值。

由题意,要求图1的通讯联络网最节省经费方案即转化求为图2的最小生成树问题。

于是本次任务即为编程实现最小生成树的构造。

 

五、软件设计

(1)程序框架

 

(2)子函数

1)确定某个元素在图中的位置

循环体,判断

2)构造连通网

定义结构体变量→循环体输入顶点元素→初始化邻接矩阵→循环体输入边及权值

3)打印连通网(邻接矩阵的存储结构)

内嵌的循环体

4)构造最小生成树

初始化辅助数组→将起始元素u加入数集U→选择其余的n-1个点→打擂台法确定最小值→选择数集V-U中最小的权值→打印所求的边(最小生成树的树枝)→将新结点归入数集U→更新数集V-U中的最小权值及其对应顶点

 

(3)结构体

1)顶点信息结构体(存储权值信息或是连接于非连接信息)

2)图的数组存储结构体

3)最小生成树的辅助数组结构体

六、编码实现

源代码如下:

#defineINFINITY999

#defineMAX_VERTEX_NUM20

#defineVertexTypeint

#defineVRTypeint

#defineNULL0

#defineInfoTypeint

typedefintGraphKind[10];

#include

#include

#include

#include

#include

#include

#include

#include

#include

#defineTRUE1

#defineFALSE0

#defineOK1

#defineERROR0

#defineINFEASIBLE-1

typedefintStatus;

typedefintBoolean;

typedefstructArcCell

{

VRTypeadj;//顶点类型,可以是权值信息或是连接于非连接信息

InfoType*info;

}ArcCell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];

typedefstruct

{

VertexTypevexs[MAX_VERTEX_NUM];

AdjMatrixarcs;

intvexnum;

intarcnum;

GraphKindkind;

}MGraph;

struct

{

VertexTypeadjvex;

VRTypelowcost;

}closedge[MAX_VERTEX_NUM];

intLocateVex(MGraphG,VertexTypeu)

{/*初始条件:

图G存在,u和G中顶点有相同特征

操作结果:

若G中存在顶点u,则返回该顶点在图中位置;否则返回-1*/

inti;

for(i=0;i

{

if(u==G.vexs[i])

returni;

}

return-1;

}

intCreateUDN(MGraph*G)

{

inti,j,k;

intv1,v2,w;

intt1,t2,t3;

//intIncInfo;

printf("请输入元素个数和边数:

");

scanf("%d%d",&t1,&t2);

G->vexnum=t1;

G->arcnum=t2;

printf("开始输入元素:

\n");//对结构体变量输入元素

for(i=0;ivexnum;++i)

{

scanf("%d",&t3);

G->vexs[i]=t3;

}

for(i=0;ivexnum;++i)//初始化邻接矩阵

for(j=0;jvexnum;++j)

{

G->arcs[i][j].adj=INFINITY;

G->arcs[i][j].info=0;

}

printf("开始输入边及权值,格式为边n:

顶点1顶点2权值\n");

for(k=0;karcnum;++k)//输入边及权值

{

printf("边%d:

",k+1);

scanf("%d%d%d",&v1,&v2,&w);

i=LocateVex(*G,v1);j=LocateVex(*G,v2);

G->arcs[i][j].adj=w;

if(G->arcs[i][j].info)

scanf("%d",G->arcs[i][j].info);

G->arcs[j][i]=G->arcs[i][j];

}

returnOK;

}

voidPrintMGraph(MGraph*G)

{

inti,j;

printf("图的邻接矩阵表示为:

\n");

for(i=0;ivexnum;++i)

{

for(j=0;jvexnum;++j)

printf("%-5d",G->arcs[i][j].adj);

printf("\n");

}

}

voidMiniSpanTree_PRIM(MGraphG,VertexTypeu)

{

inti,j,k,m=0,n=0,t=0;

k=LocateVex(G,u);//确定起始元素u在矩阵图中的位置

for(j=0;j

if(j!

=k)

{

closedge[j].adjvex=u;

closedge[j].lowcost=G.arcs[k][j].adj;

}

closedge[k].lowcost=0;//将起始元素u加入数集U

for(i=1;i

{

m=0;

//k=minimum(closedge);

while(!

closedge[m].lowcost)

m++;

t=closedge[m].lowcost;//打擂台法确定最小值,但是要保证t的初值不为零

for(m=0;m

{

if((closedge[m].lowcost!

=0)&&(closedge[m].lowcost<=t))

{

t=closedge[m].lowcost;

n=m;

//k=m;

}

}

k=n;

printf("(%d,%d)",closedge[k].adjvex,G.vexs[k]);//打印所求的边(最小生成树的树枝)

closedge[k].lowcost=0;//将新结点归入数集U

for(j=0;j

{

if(G.arcs[k][j].adj

{

closedge[j].adjvex=G.vexs[k];//顶点信息

closedge[j].lowcost=G.arcs[k][j].adj;//权值信息

}

}

}

}

voidmain()

{

intu;

MGraphGG;

MGraph*G=&GG;

CreateUDN(G);

PrintMGraph(G);

printf("要开始生成图的最小生成树,请输入顶点信息:

");

scanf("%d",&u);

printf("最小生成树为:

\n");

MiniSpanTree_PRIM(*G,u);

printf("\n");

getchar();

getchar();

}

 

七、软件测试

(1)编译环境为MicrosoftVisualStudio2010,运行最小生成树.exe,

(2)输入元素个数6,边数10

(3)输入元素:

123456

(4)输入各边及权值数据,出现图的邻接矩阵表示,其中999代表顶点不相邻

(5)输入顶点,开始生成最小生成树

(6)最小生成树为(1,6)(6,2)(1,5)(6,3)(1,4)

结论:

程序顺利完成了构造最小生成树的功能,

得到了最后解决方案如右图所示:

 

(三)

心得体会:

这四天的数据结构课程设计,我顺利完成了两个课题。

应该说过程是辛苦的,但收获是丰盛的。

我耐心写好课题规划,设计程序框图,我不担心准备的时间过长,因为我觉得准备充分了后面才做得顺利,才不需要返工。

事实正是如此,我分析了任务定义,详细研究了哈希表和最小代价生成树的思路和算法,然后画出大致的程序框图,理清思路,边写代码边参考我拟定的程序框图,这样代码写下来就更加清晰。

但是书本给的算法并不是完整的代码语言,我在将算法思想转化为代码语言时也遇到过诸如指针引用不当,类型不匹配等令人恼怒的问题。

在不断调试的过程中,我还自己摸索了VC2010编译器强大的调试功能,像设置断点,查看局部变量等功能。

借助编译器,我一步一步调试,缩小错误范围,找到并修正错误,最后完成了程序调试,出结果的那一瞬间,我激动万分。

的确,自己亲手做课程设计是挺辛苦,但我知道,过程越是坎坷曲折,收获的知识与能力越是刻骨铭心。

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

当前位置:首页 > 小学教育 > 学科竞赛

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

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