数据结构_Chapter1.1 引子

浙大陈越老师主编《数据结构》(第2版)学习笔记

什么是数据结构?让我们在解决问题的过程中,得到对数据结构的理解。

目录

1、数据组织方式

2、空间利用效率

3、算法巧妙程度


1、数据组织方式

例1.1  如果你是书店的主人,该如何摆放你的书,才能让读者很方便地找到《数据结构》这本书?

问题分析:

1、如何插入书本

2、如何查找书本

方法1:随便放

插入书本方便:哪有空插哪儿

查找书本困难:翻遍书架的每本书,才能确定地说找不到书

方法2:按照书名的拼音字母顺序摆放

插入书本痛苦:如果新书书名以A开头,得把后面所有书往后挪,才能给新书挪出位置

查找书本相对方便

方法3:书架划分区域,分类摆放;每个分类的书,按照书名拼音字母顺序摆放

与方法2相比,插入和查找,工作量都减少很多

问题1:书架划分区域时要为新书预留空间,可能造成空间浪费

问题2:类别分得越细,某一类内部查找、插入工作量越小,但查找某一类所在位置又成了麻烦

所以:解决问题的方法的效率和 数据的组织方式 有关

2、空间利用效率

例1.2  写程序实现一个函数printN,传入参数正整数N,打印从1到N的正整数

方法1:循环语句实现:

void printN_1(int n)
{
	/* 打印从1到N的全部正整数(循环) */
	int i;

	for(i = 1; i <= n; i++)
	{
		printf("%d\n", i);
	}

	return;
}

方法2:递归实现

void printN_2(int n)
{
	/* 打印从1到N的全部正整数(递归) */
	if (n > 0)		/* 注意:递归调用需要一个终止条件 */
	{
		printN_2(n - 1);
		printf("%d\n", n);
	}

	return;
}

调用printN:

int main()
{
	int N = 0;
	
	printf("Please input a number: \n");
	scanf_s("%d", &N);
	printf("number is %d \n", N);

	printN_1(N);
	return 0;
}

 测试输入N为100、1000、10000、100000的情况

当N为100000时

递归方式的printN拒绝工作了:

而循环方式printN仍然正常工作:

所以:解决问题的方法的效率还跟 空间利用效率 有关

3、算法巧妙程度

例1.3 写程序计算给定多项式在给定点x处的值

f(x) = a_{0} + a_{1} x + a_{2}x^{2} + ... + a_{n - 1}x^{n-1} + a_{n}x^{n}

方法1:循环累计求和

/* 循环累计求和 */
double polynomial_1(unsigned int n, double a[], double x)
{
    unsigned int i;
    double result = 0;

    for(i = 0; i <= n; i++)
    {
        result += (a[i] * pow(x, i));
        // printf("index[%d] a[%.2f] result %.2f \n", i, a[i], result);
    }

    return result;
}

方法2:南宋数学家秦九韶提出的算法(不断提取公因式x来减少乘法运算次数)

以n=3为例来分析:

f(x) = a_{0}+ a_{1}x+ a_{2}x^{2} + a_{3}x^{3} = a_{0} + x(a_{1} + x(a_{2} + x(a_{3}) )

/* 秦九昭:不断提取公因式x 
* f(X) = a0 + a1 * X + a2 * X^2 + a3 * X^3 
*      = a0 + X * (a1 + X * (a2 + X * a3))
*/
double polynomial_2(unsigned int n, double a[], double x)
{
    double result;
    unsigned int i;

    result = a[n];
    for(i = n; i > 0; i--)
    {
        result = a[i -1] + (x * result);
    }

    return result;
}

用于计算运行时间的程序:

typedef double (*polynomial_func)(unsigned int n, double a[], double x);

void run_func(polynomial_func func, unsigned int n, double a[], double x, unsigned int exec_count)
{
    clock_t start;
    clock_t stop;
    unsigned int i;
    double duration;
    double result;

    start = clock();
    for(i = 0; i < exec_count; i++)
    {
        result = func(n, a, x);
    }
    stop = clock();

    /* 计算运行时间,CLK_TCK是机器时钟每秒所走的时钟打点数 */
    duration = ((double)(stop - start))/CLK_TCK;
    printf("exec count[%d], duration is %.2f(s) \n", exec_count, duration);
    printf("result is %.2f \n", result);

    return;
}

调用:

#include <stdio.h>
#include <time.h>
#include <math.h>
#include <stdlib.h>

int main()
{
    double x = 0;
    int n = 3;
    int exec_count = 100;
    double* a = NULL;
    int i;

    printf("please input x :\n");
    scanf("%lf", &x);

    printf("please input n :\n");
    scanf("%d", &n);

    printf("please input exec count :\n");
    scanf("%d", &exec_count);
    if(n < 0 || exec_count <= 0)
    {
        printf("ERROR: invalid param: n[%d] exec count[%d] \n",
        n, exec_count);
        return -1;
    }

    printf("x[%.2f] n[%d] exec coun[%d] \n", x, n, exec_count);

    a = (double*)calloc(1, (n + 1) * sizeof(double));
    if(NULL == a)
    {
        printf("ERROR: malloc for a failed! \n");
        return -1;
    }

    for(i = 0; i <= n; i++)
    {
        a[i]= i;
    }

    printf("\n polynomial_1: \n");
    run_func(polynomial_1, n, a, x, exec_count);

    printf("\n polynomial_2: \n");
    run_func(polynomial_2, n, a, x, exec_count);

    free(a);

    return 0;
}

运行结果:

所以:解决问题的方法的效率也跟 算法巧妙程度 有关

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值