1.解决问题方法的效率,跟数据的组织方式有关
例:写程序实现一个函数PrintN,使得传入一个正整数为N的参数后,能顺序打印从1到N的全部正整数
——循环实现
#include<stdio.h>
void printN(int N)//printN的一个循环函数
{
int i;
for (i=1;i<= N;i ++)
{
printf("%d\n",i);
}
}
int main()
{
int s;
scanf("%d",&s);
printN(s);//在主函数里调用循环函数
return 0;
}
——递归实现
#include<stdio.h>
void printN(int N)
{
if (N){
printN(N-1);
printf("%d\n",N);
}
return;
}
int main()
{
int s;
scanf("%d",&s);
printN(s);
return 0;
}
for循环
int i;
for(i=0; i<3; i++) 强调内容
// i=0是初始化部分;i<3是循环判断条件部分(当满足此条件时才进入执行for循环中的语句);i++是执行完循环体语句后的操作
{
printf(“HelloWorld”);
}
// 上面的for语句就是控制输出3次HelloWorld“+=”的代码
a+=b等效于 a=a+b //将b的值取出再取出c的值,相加然后赋给b
a-=b 等效于 a=a-b
a*=b 等效于 a=a*b
pjz/=n 等效于 pjz=pjz/n
a%=b等效于 a=a%b
2.解决问题方法的效率,跟空间的利用效率有关
例:写程序计算给定多项式在给定点x处的值
——直接地表达方式
double f1(int n,doube a[],double x)
{
int i;
double p=a[0];
for(i=1;i<=n;i++)
p+=(a[i]*pow(x,i));//poe(x,i)意思是x的i次方
return p;
}
——将式子转换为如下的表达方式
double f2(int n; double a[];double x)
{
int i;
double p=a[n];
for (i=n;i>0;i--)
p=a[i-1]+x*p;
return p;
}
clock():捕捉从程序开始运行到clock()被调用时所耗费的时间,这个时间单位是clock tick,即“时钟打点”。
常数CLK_TCK(或CLOCKS_PER_SEC):机器时钟每秒所走的时钟打点数。
#include <stdio.h>
#include <time.h>
clock_t start,stop;
/*clock_t是clock()函数返回的变量类型*/
double duration;
/*记录被测函数运行时间,以秒为单位*/
int main ()
{
/*不在测试范围内的准备工作写在clock()调用之前*/
start=clock ();/*开始计时*/
MyFunction(); /*把被测函数加在这里*/
stop=lock(); /*停止计时*/
duration=((double)(stop-start))/CLK_TCK;
/*计算运行时间*/
/*其他不在测试范围的处理写在后面,例如输出duration的值*/
return 0;
}
例:写程序计算给定多项式在给定点x=1.1处的值f(1.1)
#include<stdio.h>
#include<time.h>
#include<math.h>/*因为pow函数*/
clock_t start,stop;
double duration;
#define MAXN le7/*多项式最大项数,即多项式阶数+1*//*被测函数最大重复调用次数*/
double f1(int n,double a[],double x);
double f2(int n,double a[],double x);
int main()
{
int i;
double a[MAXN];/*储存多项式的系数*/
for(i=0;i<MAXN;i++) a[i]=(double)i;
start=clock();
for(i=0;i<MAXN;i++);
f1(MAXN-1,a,1.1);
stop=clock();
duration=((double)(stop-start))/CLK_TCK/MAXK;
printf("ticks1=%f\n",(double)(stop-start));
printf("duration1=%3.2e\n",duration);
start=clock();
f2(MAXN-1,a,1.1);
stop=clock();
duration=((double)(stop-start))/CLK_TCK;
printf("ticks2=%f\n",(double)(stop-start));
printf("duration2=%6.2e\n",duration);
return 0;
}
(发现是运行时间太短,短到无法捕捉到数据)
让被测函数重复运行充分多次,使得测出的总的时钟打点间隔充分长,最后计算被测函数平均每次运行的时间即可!
#include<stdio.h>
#include<time.h>
#include<math.h>/*因为pow函数*/
clock_t start,stop;
double duration;
#define MAXN 10/*多项式最大项数,即多项式阶数+1*/
#define MAXK 10000000/*被测函数最大重复调用次数*/
double f1(int n,double a[],double x);
double f2(int n,double a[],double x);
double f1(int n,double a[],double x)
{
int i;
double p=a[0];
for(i=1;i<=n;i++)
p+=a[i]*pow(x,i);
return p;
}
double f2(int n,double a[],double x)
{
int i;
double p=a[n];
for(i=n;i>0;i--)
p=a[i-1]+x*p;
return p;
}
int main()
{
int i;
double a[MAXN];/*储存多项式的系数*/
for(i=0;i<MAXN;i++) a[i]=(double)i;
start=clock();
for(i=0;i<MAXK;i++)/*重复调用函数以获得充分多的时钟打点数*/
f1(MAXN-1,a,1.1);
stop=clock();
duration=((double)(stop-start))/CLK_TCK/MAXK;/*计算函数单次运行的时间*/
printf("ticks1=%f\n",(double)(stop-start));
printf("duration1=%3.2e\n",duration);
start=clock();
for(i=0;i<MAXK;i++)/*重复调用函数以获得充分多的时钟打点数*/
f2(MAXN-1,a,1.1);
stop=clock();
duration=((double)(stop-start))/CLK_TCK/MAXK;
printf("ticks2=%f\n",(double)(stop-start));
printf("duration2=%6.2e\n",duration);
return 0;
}
3.解决问题方法的效率,跟算法的巧妙程度有关
所以到底什么是数据结构??
- 数据对象在计算机中的组织方式
逻辑
物理储存结构 - 数据对象必定与一系列加在其上的操作相关联
- 完成这些操作所用的方法就是算法
抽象数据类型
- 数据类型
数据对象集
数据集合相关联的操作集 - 抽象:描述数据类型的方法不依赖于具体实现
与存放数据的机器无关
与数据储存的物理结构无关
与实现操作的算法和编程语言均无关
只描述数据对象集合相关操作集“是什么”,并不涉及“如何做到”的问题