事先说明,我用的课本是陈越主编的《数据结构》第2版
1、递归输出1~N
课本代码及我的解释:
#include<stdio.h>
void PrintN(int N) //先定义函数
{
if(N>0) //循环条件
{
PrintN(N-1);
//原先没运行之前我想不通为什么就可以顺序输出,其实这里表示调用PrintN()函数
//也就是说在执行 printf N 下面的语句之前,先解决了上面的 PrintN(),直到遇到了 PrintN(1),它里面的 PrintN(0) 执行不了了,那就执行了它的下一条语句,这时候 1 就可以输出了,然后这个递归函数就一直返回去,直到输出 N
printf("%d\n",N);
}
}
int main()
{
int n;scanf("%d",&n);
PrintN(n);
return 0;
}
在上面的代码中,如果我调换 PrintN() 中 if 的执行语句,变成
if(N>0)
{
printf("%d\n",N);
PrintN(N-1);
}
这时候就会逆序输出 N 个数。
2、测试函数
比较秦九韶算法与直接法的效率差别
课本的 MAXN=10,然后我运行得到的时间非常非常小,然后我就改了个一千以上的
#include<stdio.h>
#include<math.h>
#include<time.h>
clock_t start,stop; //clock_t是 clock()函数返回的变量类型
double duration; //记录被测函数运行时间,以秒为单位
#define MAXN 2000
#define MAXK 1e7 //被测函数最大调用次数
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;
}
void run(double(*f)(int ,double *,double),double a[], int case_n)
//此函数用于测试被测函数 (*f) 的运行时间,并且根据 case_n 输出相应的结果
// case_n 是输出的函数编号:1 代表函数 f1 2 代表函数f2
{
int i;
start=clock(); //开始计时
for(i=0;i<MAXN-1;i++) //重复调用函数 以获得充分多的时钟打点数
(*f)(MAXN-1,a,1.1);
stop=clock(); //停止计时
duration=((double)(stop-start))/CLK_TCK/MAXK; //计算运行时间
// CLK_TCK是机器时钟每秒所走的时钟打点数
printf("ticks%d=%f\n",case_n,(double)(stop-start));
printf("duration%d=%6.2e\n",case_n,duration);
}
int main()
{
int i;
double a[MAXN]; //存储多项式的系数
for(i=0;i<MAXN;i++) //赋值 a[i]=i
a[i]=(double)i;
run(f1,a,1);
printf("\n");
run(f2,a,2);
return 0;
}
以上运行出的 f1 用了403s,f2 用了 30s,差别挺大的。
3、抽象数据类型
抽象数据类型(Abstract Data Type)是一种对 “数据类型” 的描述,这种描述是抽象的。(我只是课本的搬运工)
“数据类型” 描述两方面的内容:
- 数据对象集
- 与 数据集合相关联的操作集
简而言之,抽象数据类型 只描述数据对象集和相关操作集“是什么”,并不涉及“如何做到”的问题。
课本给出的例子是 矩阵 的抽象数据类型定义
它包括 类型名称:矩阵
数据对象集:a[i][j]
操作集:对矩阵的一些操作,比如返回矩阵的行或列数,返回矩阵的某个元素等等。