数据结构课程设计 -万年历

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

学生实验报告
实验课名称:数据结构
实验项目名称:万年历
专业名称:计算机科学与技术
班级:44444444444444
学号:4444444444444
学生姓名:古古怪怪
教师姓名:坎坎坷坷
2009年 6 月28 日
一、实验名称:万年历
二、实验目的与要求
设计目的
1、数据结构是计算机专业的教学计划中的核心课程之一,数据结构在计算机科学中是一门综合性的专业基础课。

“数据结构”的研究不仅涉及到计算机硬件(特别是编码理论、存储装置和存取方法等)的研究范围,而且和计算机软件的研究有着更密切的关系,无论是编译程序还是操作系统,都涉及到数据元素在存储器中的分配问题。

在研究信息检索时也必须考虑如何组织数据,以便查找和存取数据元素更为方便。

因此,可以认为“数据结构”是介于数学、计算机硬件和计算机软件三者之间的一门核心课程。

在计算机科学中,“数据结构”不仅是一般程序设计(特别是非数值计算的程序设计)的基础,而且是设计和实现编译程序、操作系统、数据库系统及其他系统程序和大型应用程序的重要基础。

2、通过本项课程设计,可以培养独立思考、综合运用所学有关相应知识的能力,能更好的巩固《数据结构》课程学习的内容,掌握工程软件设计的基本方法,强化上机动手编程能力,闯过理论与实践相结合的难关!更加了解了c语言的好处和其可用性!同时增加了同学之间的团队合作精神!更加也体会到以后在工作中团队合作的重要性和必要性!
3、通过数据结构课程设计,使学生了解高级程序设计语言的结构,掌握基本的程序设计过程和技巧,掌握基本的分析问题和利用计算机求解问题的能力,具备初步的高级语言程序设计能力。

为后续各门计算机课程的学习和毕业设计打下坚实基础。

设计要求
1、能够显示星期;
2、能够显示年月日;
3、能显示十二个月;
4、能准确显示阳历的每一天;
4、格式与日历一致;
二、实验内容:
1、输出公元1年至9999年的日历;
2、以标准日历的形式输出,包含月份、星期以及具体某一天对应的年、月、
星期;
3、用数据结构课上所学二叉树及队列顺序存储形式存储;
三、程序设计思路
【一】由于万年历具有以下特点:
1。

平年365天(52周+1天),闰年366天(52周+2天)。

平年2月28天,闰年2月29天。

2。

每400年整一闰,或每4年且不为百年的一闰。

(原因:地球绕太阳一周的时间是365天5小时46秒,为了使一年的天数为整数,将一年的天数定为365天,余下的时间积累起来,四年就是23小时15分4秒,将近一天,把这一天加在某年的二月而成29天,该年称为闰年,其它年称为平年。

但四年加一天又多用了44分56秒,这个数积满400年为三天。

因此400年中只能有97个闰年,所以凡能被400整除,或不能被100整除但能被4整除的年份为闰年。

)
3。

每 4年(3个平年+1个闰年)共208周+5天——注意这个“5天”
每百年共100*(208周+5天)-1天=5217周+5天——注意这个“5天”(整百年暂设为平年)
每400年共4*(5217周+5天)+1天(整400年闰)=20871周+0天——注意这个“0天”和“1天”(4个整百年只有一个闰年) 即400年一轮回!(原来万年历400年前是一家)
【二】根据万年历以上特点进行编写:
(1)首先对万年历年、月、日进行编写,编写程序先定义每月的天数为28天,如月份为1、3、5、7、8、10、12就定义天数为31天反之如果月份为4、6、9、11就输出天数为30天,由上可见2月份为28天但是如果为闰年就有29天就要定义一个数组存放天数,用while循环控制。

(2)再对其中的星期进行编写:由于公元1月1日设为星期六,故3月1日为星期三,可以用万年3月1日星期算法(特别是那个三)
其公式为:
某年3月1日星期几=(3天+百年%4*5天+年/4*5天+年%4+月星期表+日-1天)%7 某年3月1日星期几=(百年%4*5天+年/4*5天+年%4+月星期表+日+2天)%7
或某年3月1日星期几=(百年%4*5天+年+年/4+月星期表+日+2天)%7
其中,闰4百年3月1日星期算法(百年%4=0)
其公式为:
某年3月1日星期几=(年+年/4+月星期表+日+2天)%7
例:
1600年3月1日星期几=(0+0/4+0+1+2)%7=3%7=星期三
2000年3月1日星期几=(0+0/4+0+1+2)%7=3%7=星期三
2001年3月1日星期几=(1+1/4+0+1+2)%7=4%7=星期四
2004年3月1日星期几=(4+4/4+0+1+2)%7=8%7=星期一
2008年3月1日星期几=(8+8/4+0+1+2)%7=13%7=星期六
2042年3月1日星期几=(42+42/4+0+1+2)%7=55%7=星期六
其中,平4百年3月1日星期算法(百年%4<>0)
其公式为:
某年3月1日星期几=(百年%4*5天+年+年/4+月星期表+日+2天)%7
例:1700年3月1日星期几=(17%4*5+0+0/4+0+1+2)%7=8%7=星期一(注意:1700年是平年)
1800年3月1日星期几=(18%4*5+0+0/4+0+1+2)%7=13%7=星期六(注意:1800年是平年)
1900年3月1日星期几=(19%4*5+0+0/4+0+1+2)%7=18%7=星期四(注意:1900年是平年)
1999年3月1日星期几=(19%4*5+99/4*5+99%4+3)%7=(15+120+3+3)%7=141%7=星期一
2100年3月1日星期几=(21%4*5+0/4*5+0%4+3)%7=(5+0+0+3)%7=8%7=星期一(注意:2100年是平年)
2101年3月1日星期几=(21%4*5+1/4*5+1%4+3)%7=(5+0+1+3)%7=9%7=星期二2102年3月1日星期几=(21%4*5+2/4*5+2%4+3)%7=(5+0+2+3)%7=10%7=星期三2103年3月1日星期几=(21%4*5+3/4*5+3%4+3)%7=(5+0+3+3)%7=11%7=星期四
2104年3月1日星期几=(21%4*5+4/4*5+4%4+3)%7=(5+1+0+3)%7=9%7=星期二(注意:2104年是闰年)
9999年3月1日星期几=(99%4*5+99/4*5+99%4+3)%7=(120+15+3+3)%7=141%7=星期一
注:按400年一轮回!(400年前是一家)的说法
1600年,2000年是一样的;
1700年,2100年是一样的;
1800年,2200年是一样的;
1900年,2300年是一样的。

其中万年某日星期算法
其公式为:
某日星期几=(百年%4*5天+年+年/4+月星期表+日+2天)%7
通同星期偏差表
闰年 1月 2月 3月 4月 5月 6月 7月 8月 9月 10月 11月 12月
天数 31 29 31 30 31 30 31 31 30 31 30 31 星期 3 6 0 3 5 1 3 6 2 4 0 2
平年 1月 2月 3月 4月 5月 6月 7月 8月 9月 10月 11月 12月
天数 31 28 31 30 31 30 31 31 30 31 30 31
星期 4 0 0 3 5 1 3 6 2 4 0 2
为对以上的万年历星期的算法是正确的对其进行了以下的计算:
⒈对于二十世纪任意日期可以用公式某日星期几=(百年%4*5天+年+年/4+平年月星期表+日+2天)%7=(19%4*5天+年+年/4+平年月星期表+日+2天)%7=(15天+年+年/4+平年月星期表+日+2天)%7以下就是根据上面对其进行的计算:
1900年元旦 1日=(0/4*5+0%4+1+3)%7=(0+0+4)%7=4
1月表=4(平年)故 4+4=1 即1900年元旦是星期一1949年国庆 1日=(49/4*5+49%4+1+3)%7=(60+1+4)%7=2
10月表=4(平年)故 4+2=6 即1949年国庆是星期六
1999年12月31日 31日=(99/4*5+99%4+31+3)%7=(120+3+34)%7=3
12月表=2(平年)故 2+3=5 即1999年12月31日是星期五
⒉对于二十一世纪新前年虫算法(20%4*5=0)可以用公式:某日星期几=(百年%4*5天+年+年/4+闰年月星期表+日+2天)%7 =(20%4*5天+年+年/4+闰年月星期表+日+2天)%7以下就是根据上面对其进行的计算:
2000年元旦 1日=(0+0/4+1+2)%7=(0+0+1+2)%7=3
1月表=3(闰年)故 3+3->6 即2027年元旦是星期六2018年春节 16日=(18+18/4+16+2)%7=(18+4+16+2)%7=5
2月表=0(平年)故 0+5=5 即2018年春节是星期五
2099年12月31日 31日=(99/4*5+99%4+31+2)%7=(120+3+33)%7=2
12月表=2(平年)故 2+2=4 即2099年12月31日是星期四最后,根据日期是紧挨顺序的,可用顺序存储结构存储,对年、月、星期的算法清晰之后,即可用C语言的形式及C++语言的形式编程。

【三】单元程序设计:
1、闰年函数的定义:
int IsLeapYear( int year )
{
if ((year %4 == 0) && (year % 100 != 0) || (year % 400 == 0) )
return 1;
else
return 0;
2、判断星期的程序设计:
i = Year_days % 7;
printf("Mon Tue Wed Thu Fri Sat Sun\n"); if( i != 0 )
for( temp_i = 0; temp_i < i; temp_i++) printf(" ");
day = 1;
3、用switch语句定义月份:switch( temp )
{
case 1:
printf("January(%d)\n",year);
break;
case 2:
printf("Febrary(%d)\n",year);
break;
case 3:
printf("March(%d)\n",year);
break;
case 4:
printf("April(%d)\n",year);
break;
case 5:
printf("May(%d)\n",year);
break;
case 6:
printf("June(%d)\n",year);
break;
case 7:
printf("July(%d)\n",year);
break;
case 8:
printf("Augest(%d)\n",year);
break;
case 9:
printf("September(%d)\n",year); break;
case 10:
printf("October(%d)\n",year);
break;
case 11:
printf("November(%d)\n",year);
break;
case 12:
printf(" December(%d)\n",year);
break;
4、日期的输出(分闰年及平年,用if语句和while循环实现):if( IsLeapYear(year) && temp == 2)
while( day <= month_day[12] )
{
if( day >1 )
if( Year_days % 7 == 0 )
printf(" \n");
if( day >= 10 )
printf("%3d ",day);
else
printf("%3d ",day);
Year_days++;
day++;
}
else
while (day <= month_day[temp-1])
{
if( day > 1 )
if( Year_days % 7 == 0 )
printf("\n");
if( day >=10 )
printf("%3d ",day);
else
printf("%3d ",day);
Year_days++;
day++;
}
printf("\n");
if( getch() == 'q' )
exit(0);
}
getch();
【四】程序框图:
四、程序源代码
#include <stdio.h> //标准输入输出头文件,包含getch()、
scanf()、printf()等语句
#include <iomanip.h> //I/O流控制头文件,含有"%d"(dec 置基数为10)函数
#include<iostream.h> //标准的输入输出流头文件包含scanf()、printf()、cin>> 、cout<<函数
#include<conio.h> //控制台输入输出含有getch()函数
#include<stdlib.h> //包含了的C语言标准库函数如exit()、malloc()、free()
int IsLeapYear(int); //整型闰年的定义
void main() //主程序
{
int i;
int day;
int year;
int temp;
int temp_i;
long int Year_days = 0;
int Year_Start = 1; //万年历的起始时间为公元1年
int Per_Year_Days;
int month_day[]={31,28,31,30,31,30,31,31,30,31,30,31,29}; //定义用于存放每月天数的数组,一三五七八十腊为31天,二月分28天和29天
printf("Please enter the year: ");
scanf("%d",&year); //输入年份,year用引用类型,年数不同时输出随着改变
while(Year_Start < year)
{
if( IsLeapYear( Year_Start ) ) //闰年为366天
Per_Year_Days = 366;
else
Per_Year_Days = 365; //平年为365天
Year_days = Year_days + Per_Year_Days;
Year_Start++;
}
for( temp = 1; temp <=12; temp++ ) //
{
switch( temp ) //计算temp表达式的值
{
case 1:
printf("January(%d)\n",year);//一月
break;
case 2:
printf("February(%d)\n",year);//二月
break;
case 3:
printf("March(%d)\n",year);//三月
break;
case 4:
printf("April(%d)\n",year);//四月
break;
case 5:
printf("May(%d)\n",year);//五月
break;
case 6:
printf("June(%d)\n",year);//六月
break;
case 7:
printf("July(%d)\n",year);//七月
break;
case 8:
printf("August(%d)\n",year);//八月
break;
case 9:
printf("September(%d)\n",year);//九月
break;
case 10:
printf("October(%d)\n",year);//十月
break;
case 11:
printf("November(%d)\n",year);//十一月
break;
case 12:
printf(" December(%d)\n",year);//十二月
break;
}
i = Year_days % 7; //闰年为366天年数除以7的余数
printf("Mon Tue Wed Thu Fri Sat Sun\n");
if( i != 0 )
for( temp_i = 0; temp_i < i; temp_i++)
printf(" ");
day = 1;
if( IsLeapYear(year) && temp == 2) //***此程序的核心,当为闰年时,二月有29天执行while循环,实现星期的换行
while( day <= month_day[12] )
{
if( day >1 )
if( Year_days % 7 == 0 ) //控制每月第一天的位置,满足余数为0
时,另起一行
printf(" \n");
if( day >= 10 )
printf("%3d ",day); //***C语言域宽的设置 %3d表示相邻天数的域宽为3,星期的排列整齐
else
printf("%3d ",day);
Year_days++;
day++;
}
else
while (day <= month_day[temp-1]) //平年的月份
{
if( day > 1 )
if( Year_days % 7 == 0 ) //与闰年时执行条件一样
printf("\n");
if( day >=10 )
printf("%3d ",day);
else
printf("%3d ",day);
Year_days++;
day++;
}
printf("\n");
if( getch() == 'q' )
exit(0); //满足条件时退出
}
getch(); //不满足条件时执行getch()语句
}
int IsLeapYear( int year ) //闰年的定义
{
if ((year %4 == 0) && (year % 100 != 0) ||
(year % 400 == 0) )
return 1;
else
return 0;
}
五、实验结果与分析
【一】实验结果:
(1)2009年1、2、3、4、5、6月:
(2)7、8、9、10、11、12月:
(3)公元100年:公元9999年:
【二】结果分析:
(1)日历的形式为阳历,输出范围为公元1年至公元9999年;
(2)输出结果满足设计要求,可以输出月份,星期,日期且以现在日历的形式输出;
(3)结果能有效区分闰年及平年,每一天的具体天数;
(4)每月前的空格及数字之间的域宽都满足要求:【三】算法效率分析:
(1)时间复杂度:算法中程序的调用都为单层函数调用,没有函数的多层套用,所以时间复杂度为线性阶,即为O(n);
(2)空间复杂度:数据的存取以顺序存储方式存取,没有空间的浪费和压缩存储的现象,所以空间复杂度为O(n)。

六、心得体会:
1. 经过上一个学期对《数据结构》的学习,我们学习了理论知识,了
解了C语言程序设计的思想,这些知识都为我们的下一步学习打下了坚
实的基础。

通过课程设计,一方面是为了检查我们一个学期来我们学习
的成果,另一方面也是为了让我们进一步的掌握和运用它,同时也让我
们认清自己的不足之处和薄弱环节,加以弥补和加强。

通过对万年历的
设计进一步的巩固了用c语言和C++编写程序,并且有利于更好的掌握
程序设计语言!
2. 在万年历的编写过程中也体会到了做事情一顶要细心、认真。

更加
知道了要掌握好基础知识。

还有体会到了成功的感觉!在万年历的设计
过程中更加体会到了团队合作的重要性,在设计的过程中,曾遇到好多
难解的问题,经过与同学的讨论才得以解决,常言道:“一个诸葛亮比
不上三个臭皮匠。

”知道了只有团队合作才会更好的完成设计!也体会
到以后在工作中团队合作的必要性和重要性!
3. 通过本项课程设计也培养了我独立思考、综合运用所学有关相应
知识的能力,掌握工程软件设计的基本方法,强化上机动手编程能力,
闯过理论与实践相结合的难关!
4. 由于程序设计语言是近年在国内外得到迅速推广应用的一种语言。

它功能丰富,表达能力强,使用灵活方便,应用面广,目标程序效率高,
可移植性好,既具有高级语言的优点,又具有低级语言的许多特点。


过这次的程序设计更加了解了语言设计的好处和其可用性!
5. 在这次课程设计中也知道了自己的动手能力不强有待进一部的提
高!在设计过程中不能够把书本上的知识与实践相结合,这也就增加了
设计不好该程序的想法!在设计过程中的一次次设计错误增加了我放弃
的想法!不过经过自己的独立思考和同学的帮助终于完成了课程设计!
完成该程序后想起自己以前的每一次对自己失去信心,就觉得并不是在
知识掌握上打败了,而是自己对自己缺乏信心!只要自己对自己不失去
信心相信就可以完成那些以前认为完成不了的事情!也让我懂得了要想
成功首先就必须有很强的自信心!懂得了自己以后要在做任何事情时都
要自信!当自己都不相信自己能够成功时还可能会获得成功吗?
6. 在课程设计的过程中也知道了自己在以前的学习中有很大的不足导
致在设计过程中出现了很多的问题,有些地方看不懂也不知道怎么去设
计,但是在设计过程中也学习了很多,掌握了自己以前没有学好的知识,
虽然一时可以掌握完以前没有学好的知识,不过也给自己敲响了警钟,
在学习中不可以伏于表面,要想学好每一门课程都要踏踏实实,做什么
都不是给别人看的!都是要更好的掌握该门知识,提高自己的自身的修
养,提高自己的能力!为以后的工作打下良好的知识基础和技能基础!
七、老师评语:。

相关文档
最新文档