数据结构课程设计.docx

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

数据结构课程设计.docx

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

数据结构课程设计.docx

数据结构课程设计

数据结构课程设计

题目:

家谱管理系统设计与实现

姓名:

何健良

学号:

200814602013006

一.需求分析

1.记录某家族历代的家族成员情况及关系,对家谱的存储、更新、查询、统计等的操作。

2.存放记录家谱以后缀名为txt的文件形式记录家谱中各成员的信息。

3.家族成员信息中均包含以下内容:

如姓名、出生地、出生日期、死亡日期、性别、身高、学历、职业、职称。

4.能对修改后存盘的家谱文件进行随时的修改及更新,方便操作。

5.文件中打印的家谱及读出的家谱,应该形成树状的关系。

6.家谱建立好后,以Dos(或windows下的命令行模式)字符方式下运行。

7.显示第n代人的所有信息(即家谱所有人的信息),并查询家谱中已有姓名的信息。

8.按亲属关系的方式进行查询,输出上下亲属关系的姓名。

9.随意出进添加某人的孩子,及删除某人(若其存在后代,则一并删除)。

10.修改某人的信息。

11.统计家族中的相关信息(如:

平均寿命、平均身高、男女比例、家庭平均人口、平无(最高/低)学历等…..)

二.概要设计

采用二叉树进行家谱的管理,并以友好的输出形式展示,具有支持鼠标、全屏的可视化操作、树形显示家族,现程序涉及围绕家谱管理软件的类型,但基本操作者在”家谱”类型中。

1.定义”个人的信息”类型:

ADTPerson{

数据对象:

D={Pj|Pj={姓名、出生日期、性别、出生地、出生日期、死亡日期、学历、身高、职业、职称},j=0,1,2,3……n,其中n>=0}

数据关系:

R={}

基本操作:

}ADTPerson

2.定义”家谱类型文件”类型

ADTFamilyTypeFile{

数据对象:

D={Aj|Aj属于person,j=1,2,3,……,n其中n>=1}

数据关系:

D中每个对象用特定的字符隔开,

R={|Aj属于D,j=1,2,3,……n,其中n>=1,String属于字符串类型,为Aj父亲姓名(若String=-1,Aj无父亲,若String=Aj的姓名,表示家谱文件结束)}

基本操作:

1.打开家谱类型文件(.txt),建立兄弟、孩子二叉树。

2.从内存读取兄弟、孩子二叉树,并建立家谱类型文件。

}ADTFamilyTypeFile

3.定义”家谱”类型

ADTFamily{

数据对象:

D={Aj|Aj属于Person,j=1,2,3……n其中n>=0}

数据关系:

V={|aj-1,aj属于D,j=2,3,…..n其中n>=2,且Aj-1与Aj为祖先与后代关系(parent),判断是否有后代,及其兄弟的关系,能过二叉链表表示}

基本操作:

1.显示某人信息。

2.修改某人信息。

3.增加某人孩子。

4.删除某人。

5.通过某人查找其双亲、孩子、兄弟。

}ADTFamily

三.详细设计

1.定义”个人信息”类型

structperson

{

charsex[10],birthaddress[20],birthday[14],deathday[20];//姓名,性别,出生地,生日

charname[20],parentname[30];

charwork[15],xueli[10],consort[20],zhiche[15];//职业学历配偶职称;

charstature[10];//身高

};

2.定义”家谱类型文件”类型

{//一个人的有关信息在磁盘文件中存储结构

DWORDres;

HANDLEhIn;

INPUT_RECORDmouseRec;

hIn=GetStdHandle(STD_INPUT_HANDLE);//获取标准输入设备句柄

COORDpos={21,16},posa={33,27},posb={52,27};

buttona[10],b[2],c[2];

SetConsoleCursorPosition(hOut,pos);

a[0].createbutton(pos,"姓名",14,236,hOut);//姓名

pos.X+=30;

a[1].createbutton(pos,"性别",14,236,hOut);//性别

pos.X+=12;

c[0].createbutton(pos,"男",14,236,hOut);

pos.X+=4;

c[1].createbutton(pos,"女",14,236,hOut);

pos.Y+=2;pos.X-=46;

a[2].createbutton(pos,"身高",14,236,hOut);//身高

pos.X+=20;

SetConsoleCursorPosition(hOut,pos);

cout<<"cm";

pos.X+=10;

a[3].createbutton(pos,"配偶",14,236,hOut);

pos.Y+=2;pos.X-=30;

a[4].createbutton(pos,"出生时间",14,236,hOut);//出生时间

pos.X+=30;

a[5].createbutton(pos,"死亡时间",14,236,hOut);//死亡时间

a[5].pos1.X+=25;

SetConsoleCursorPosition(hOut,a[5].pos1);

cout<<"(如1985.01.21)";

a[5].pos1.X-=25;

pos.Y+=2;pos.X-=30;

a[6].createbutton(pos,"学历",14,236,hOut);//学历

pos.X+=30;

a[7].createbutton(pos,"职业",14,236,hOut);//职业

pos.Y+=2;pos.X-=30;

a[8].createbutton(pos,"职称",14,236,hOut);//职称

}

3.定义”家谱”类型

typedefstructbitnode

{

COORDpos;//光标位置

//intnodenum;

persona;

structbitnode*lchild,*rchild,*parent;

}bitnode,*bitree;

4.用于计算时间(寿命)函数类型

voidtime(doublea)//时间函数经过a秒后继续执行

{

clock_tstart,finish;

start=clock();

finish=clock();

while((finish-start)/CLOCKS_PER_SEC

finish=clock();

return;

}

5.用结构search存储快速查找

bitnode*search(bitree&,char*);//查找

bitnode*search(bitree&T,charname[30])//查找返回节点

{

bitnode*p,*q;

if(T)

{

if(!

strcmp(T->a.name,name))

returnT;

p=search(T->lchild,name);

q=search(T->rchild,name);

if(p)returnp;

elsereturnq;

}

returnT;

}

6.根据家谱的特点,采用孩子-兄弟的二叉树链表表示法来实现,其中,各功能(如,统计任一家庭、结果的打印、屏幕显示、全屏可视化、支持鼠标等)操作,各类实现如下。

以下是各功能类型的数据成员基本操作

classbutton//鼠标点击类

{

public:

friendBOOLmouseclickr(HANDLEhOut,HANDLEhIn,button&a,INPUT_RECORDmouseRec);//鼠标右键单击事件

friendBOOLmouseclickl(HANDLEhOut,HANDLEhIn,button&a,INPUT_RECORDmouseRec);//鼠标左键单击事件

friendvoidmousemove(HANDLE,HANDLE,button&a,INPUT_RECORDmouseRec);

friendvoidmousemove1(HANDLE,HANDLE,button&a,INPUT_RECORDmouseRec);

friendBOOLmousedoubleclick(HANDLEhOut,HANDLEhIn,button&a,INPUT_RECORDmouseRec);//鼠标双击事件

COORDpos1;

voidcreatebutton(COORD,char*,WORD,WORD,HANDLE);//创建按钮

voidhidebutton(HANDLE,BOOL);//隐藏按钮或显示按钮

intlen;

BOOLp;//控制按钮是否可见

WORDatt1,att0;//att1按钮的颜色,att0鼠标移动到按钮上时按钮的颜色

charbuttonname[30];

};

BOOLfullScreen(BOOL,button,HANDLE,HANDLE);//全屏

voidsetmenu0(button*,int,HANDLE);//初始化菜单

voidsetmenu1(button*a,intn,HANDLEh);//设置菜单

BOOLframe1(HANDLE,HANDLE);//退出对话框

BOOLframe2(HANDLE,HANDLE,char*);//单按钮对话框

intframe3(HANDLE,HANDLE);//退出对话框

voidwindows1(HANDLE,HANDLE);家谱显示窗体1

voidwindows2(HANDLE,HANDLE,bitree&);家谱显示窗体2

bitnode*cinnode(bitnode*,HANDLE);//初始化时输入第一个节点

bitnode*cinnode1(bitnode*,HANDLE);//用于修改

voidxiugai(bitnode*,HANDLE);//修改功能

button*print1(bitree,button*,int,HANDLE);//打印家谱

bitnode*searchperson(HANDLE,bitree);//查询

voidclearscreen(HANDLE,COORD,COORD);//清空屏幕的一块区域

intdelfile(char*);//删除文件

bitreecreate(HANDLE,HANDLE);//初始化

voiddestroy(bitnode*);//销毁二叉树

voidsavefile(bitree&t);//保存文件

bitreeopenfile(HANDLE);//打开文件

voidstat(bitreet,double&age,float&stature,int&mannum,int&x,int&y,int&a,int&b);//统计函数统计平均年龄身高,男女比例

voidcoutxueli(inta);//输出统计后的学历

7.为使程序结构趋于清晰,分别使用dos下鼠标支持,window1(初如化后进入的界面1),window2(打开文件后的界面2),Create(创建新的家谱文件),insert(添加新成员),print(打印家谱),del(删除成员),savefile(文件的保存),openfile(文件的打开),统计家族情况将在下的功能介绍中得到相应的概述。

四.重要函数分析.

经上述的需求分析,及重要的数据类型进行描述后,开始对实现基本的几项功能,其中:

增加成员,修改成员资料,删除成员;数据的存取:

初始化数据,保存数据,读取数据;程序框架结构:

dos下界面形成,鼠标的应用等。

1.Dos下的鼠标应用功能

讲述上面基本功能前,首先,我们要实现如在Dos下应用鼠标操作,因为这是本课程设计的一个重要前提,而本程序设计则是应用到这个关键的策略。

本课程设计之前,我认为在DOS下应用鼠标是比较难以实现的事情,因为日常我们所见到在DOS下有鼠标的,应该是加载了某程序策略来加以实现,如GHOST软件。

现在可以借这次数据结构的课程设计来认识这个功能是如何实现的,经过网上资料搜集和查看相关的书籍。

最后应用到本课程设计中的部分策略如下:

 #include

classbutton

{

public:

friendBOOLmouseclickr(HANDLEhOut,HANDLEhIn,button&a,INPUT_RECORDmouseRec);//鼠标右键单击事件

friendBOOLmouseclickl(HANDLEhOut,HANDLEhIn,button&a,INPUT_RECORDmouseRec);//鼠标左键单击事件

friendvoidmousemove(HANDLE,HANDLE,button&a,INPUT_RECORDmouseRec);

friendvoidmousemove1(HANDLE,HANDLE,button&a,INPUT_RECORDmouseRec);

friendBOOLmousedoubleclick(HANDLEhOut,HANDLEhIn,button&a,INPUT_RECORDmouseRec);//鼠标双击事件

COORDpos1;

voidcreatebutton(COORD,char*,WORD,WORD,HANDLE);//创建按钮

voidhidebutton(HANDLE,BOOL);//隐藏按钮或显示按钮

intlen;

BOOLp;//控制按钮是否可见

WORDatt1,att0;//att1按钮的颜色,att0鼠标移动到按钮上时按钮的颜色

charbuttonname[30];

};

BOOLmouseclickr(HANDLEhOut,HANDLEhIn,button&a,INPUT_RECORDmouseRec)//鼠标单击右键则返回true

{

if(a.p)

{

if(mouseRec.EventType==MOUSE_EVENT)

{

if(mouseRec.Event.MouseEvent.dwMousePosition.X>a.pos1.X&&mouseRec.Event.MouseEvent.dwMousePosition.X<=a.pos1.X+a.len&&mouseRec.Event.MouseEvent.dwMousePosition.Y==a.pos1.Y)

{

If(mouseRec.Event.MouseEvent.dwButtonState==RIGHTMOST_BUTTON_PRESSED)

{

if(mouseRec.EventType==MOUSE_EVENT)

{

if(mouseRec.Event.MouseEvent.dwMousePosition.X>a.pos1.X&&mouseRec.Event.MouseEvent.dwMousePosition.X<=a.pos1.X+a.len&&mouseRec.Event.MouseEvent.dwMousePosition.Y==a.pos1.Y)

{

if(mouseRec.Event.MouseEvent.dwButtonState==RIGHTMOST_BUTTON_PRESSED)

{

DWORDres;

ReadConsoleInput(hIn,&mouseRec,1,&res);

FillConsoleOutputAttribute(hOut,a.att1,a.len,a.pos1,NULL);

returntrue;

}

else

returnfalse;

}

elsereturnfalse;

}

elsereturnfalse;

}

else

returnfalse;

}

else

returnfalse;

}

else

returnfalse;

}

elsereturnfalse;

}

BOOLmouseclickl(HANDLEhOut,HANDLEhIn,button&a,INPUT_RECORDmouseRec)//鼠标单击左键则返回true

{

if(a.p)

{

………………………//省略部分代码段

BOOLmousedoubleclick(HANDLEhOut,HANDLEhIn,button&a,INPUT_RECORDmouseRec)//鼠标双击击按钮则返回true

{

if(a.p)

{

if(mouseRec.EventType==MOUSE_EVENT)

{

if(mouseRec.Event.MouseEvent.dwMousePosition.X>a.pos1.X&&mouseRec.Event.MouseEvent.dwMousePosition.X<=a.pos1.X+a.len&&mouseRec.Event.MouseEvent.dwMousePosition.Y==a.pos1.Y)

{

if(mouseRec.Event.MouseEvent.dwEventFlags==DOUBLE_CLICK)

{

FillConsoleOutputAttribute(hOut,a.att1,a.len,a.pos1,NULL);

returntrue;//

}

else

returnfalse;

}

else

returnfalse;

}

else

returnfalse;

}

elsereturnfalse;

}

在上述代码段的分析所知,本程序分别定义,鼠标的单击事件,双击事件,右键单击事件,左键单击事件,其中这让我体会最深刻的是,原来用C++语言在DOS下写一个鼠标事件是这么繁锁的事,因为我自己从事web程序开发,在WEB做鼠标事作,只要ONCLICk,doubleClick等提交javascript(自己设定的过程)就行了,根本就不用考虑编译器中已做的翻译.不过用C来实现,至少可以认识下如何在DOS下做操作的。

2.Dos下的界面显示

由于本程序设计是在Dos下运行,我们都知道,DOS下是没有图形界面的,因此,为了使界面美化及更人性化这个特点去出发,因此特意在本程序中应用到window类,其中在初始化进入前台时用voidwindows1(HANDLEhOut,HANDLEhIn)函数,显示出文件操作,方便调用保存好的家谱文件,同时,当经过windows1函数后,进入voidwindows2(HANDLEhOut,HANDLEhIn,bitree&t)函数窗口,这一步已经是打开了某个家谱文件后进入的窗口,初始化所有的基本功能及高极打印功能等。

其实在windows1函数是比较容易实现的事,只要调用相关的关键函数(如window类,button类[上面已分析],)基本可以实现,唯一是难于实现的是如果调用某家谱的文件呢?

这样涉及到文件的操作,其中更DEBUG调试出现了打开文件,提示有野指针的现象错误中提示到”DEBugAssertionFailed!

Dbgheap。

cexpression:

_CrtIsValidHeapPointer(pUserData)”经过相关的资料搜索,到现在DEBUG调试还没有得到答案,但是有replace调试中这个错误是被覆盖,但是这样不符合软件工程测试,希望老师能给出答案。

而关于windows2函数则是集成了本次程序设计的所有基本功能和高级功能在里面,这也是实现时间最长的一步,当中涉及到快速排序,栈的操作得的算法,知识的应用之广。

下面给出两个函数的部分代码。

voidwindows1(HANDLEhOut,HANDLEhIn)//操作窗口1

{

BOOLtal=true;

INPUT_RECORDmouseRec;

DWORDres;

hOut=GetStdHandle(STD_OUTPUT_HANDLE);//获取标准输出设备句柄

hIn=GetStdHandle(STD_INPUT_HANDLE);//获取标准输入设备句柄

CONSOLE_SCREEN_BUFFER_INFObInfo;//窗口缓冲区信息

GetConsoleScreenBufferInfo(hOut,&bInfo);//获取窗口缓冲区信息

COORDsize={600,600},posText={0,0};

SetConsoleScreenBufferSize(hOut,size);//重新设置缓冲区大小

SMALL_RECTrc={10,20,100,52};//重置窗口位置和大小

SetConsoleWindowInfo(hOut,true,&rc);

COORDp={1,1},poss={0,10},poss1={0,0},poss2={20,11};

COORDposa={40,5},pos1={10,15},posb={53,5},posc0={35,2};

COORDposc1={34,1},posc2={34,3},posc3={34,2},posc4={48,2};

FillConsoleOutputCharacter(hOut,'',bInfo.dwSize.X*bInfo.dwSize.Y-1,posText,NULL);

FillConsoleOutputAttribute(hOut,14,bInfo.dwSize.X*bInfo.dwSize.Y-1,posText,NULL);

SetConsoleTextAttribute(hOut,14);//设置窗口属性

SetConsoleCursorPosition(hOut,p);//设置光标的位置

………..//省

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

当前位置:首页 > 医药卫生 > 基础医学

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

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