1. 数据结构基础
1.1 什么是数据结构
1.1.1 关于数据组织—例:图书摆放
例1:如何在书架上摆放图书?
- 分类
- 二分查找
解决问题方法的效率,跟数据的组织方式有关。
1.1.2 关于空间使用—例:PrintN函数实现
例2:写程序实现一个函数PrintN,使传入一个正整数为N的参数后,能顺序打印从1到N的全部正整数。
/* 循环实现 */
void PrintN (int N)
{
int i;
for (i = 1; i <= N; i ++){
printf("%d\n", i);
}
return;
}
/* 递归实现 */
void PrintN (int N)
{
if (N){
PrintN(N - 1);
printf("%d\n", N);
}
return;
}
/* 测试函数 */
#include <stdio.h>
void PrintN (int N);
int main ()
{
int N;
scanf("%d", &N);
PrintN(N);
return 0;
}
令N=100,1000,10000,100000……
当N=100000时,循环实现能顺序打出从1到100000的所有正整数,递归实现却只能打印100000这一个数。(有时递归程序代码量少,但空间占用却很多)
解决问题方法的效率,跟空间的利用效率有关。
1.1.3 关于算法效率—例:计算多项式值
例3.1:写程序计算给定多项式在给定点处的值。
f ( x ) = a 0 + a 1 x + ⋯ + a n − 1 x n − 1 + a n x n f(x)=a_{0}+a_{1}x+\dots+a_{n-1}x^{n-1}+a_{n}x^{n} f(x)=a0+a1x+⋯+an−1xn−1+anxn
/* 程序一 */
double f (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;
}
这是最直接的方式,但绝对会被专业程序员鄙视的。
巧妙的方式——结合律:将多项式加以变换得到:
f ( x ) = a 0 + x ( a 1 + x ( … ( a n − 1 + x ( a n ) ) … ) ) f(x)=a_{0}+x(a_{1}+x(\dots(a_{n-1}+x(a_{n}))\dots)) f(x)=a0+x(a1+x(…(an−1+x(an))…))
/* 程序二 */
double f (int n, double a[], doucle x)
{
int i;
double p = a[];
for (i=n; i>0; i--)
p = a[i-1] + x*p;
return p;
}
通过计时程序可以测出程序二明显比程序一运行快。
使用clock()
可以捕捉从程序开始运行到clock()
被调用时所耗费的时间,时间单位是clock tick
,即”时钟打点”。常数CLK_TCK
为机器时钟每秒所走的时钟打点数。
/* clock()计时程序 */
#include <stdio.h>
#include <time.h>
clock_t start, stop;
/* clock_t是clock()函数返回的变量类型 */
double duration;
/* 记录被测函数运行时间,以秒为单位 */
int main ()
{
/* 不在测试范围内的准备工作写在clock()调用之前 */
start = clock(); /* 开始计时,start里存放的是从main()开始执行到本次clock()调用时一共走了多少个ticks */
MyFunction(); /* 把被测函数加在这里 */
stop = clock(); /* 停止计时,stop里存放的是从main()开始执行到本次clock()调用时一共走了多少个ticks */
duration = ((double)(stop - start))/CLK_TCK;
/* 计算运行时间,单位为秒 */
/* 其他不在测试范围的处理写在后面,例如输出duration的值 */
return 0;
}
例3.2:写程序计算给定多项式 f ( x ) = ∑ i = 0 9 i ⋅ x i f(x)=\sum_{i=0}^{9}i{\cdot}x^{i} f(x)=∑i=09i⋅xi在给定点 x = 1.1 x=1.1 x=1.1处的值 f ( 1.1 ) f(1.1) f(1.1)。
/* 程序一 */
double f1 (int n, double a[], double x)
{
int i;
double p = a[0];
for (i=1; i<=n; i++)
p += (a[i] * pow(w, i));
return p;
}
/* 程序二 */
double f2 (int n, double a[], doucle x)
{
int i;
double p = a[];
for (i=n; i>0; i--)
p = a[i-1] + x*p;
return p;
}
/* 测试程序 */
#include <stdio.h>
#include <time.h>
#include <math.h> /* pow()函数 */
double duration;
#define MAXN 10 /* 多项式最大项数,即多项式阶数+1 */
double f1