浙江大学-数据结构-慕课-第一节学习笔记

174 阅读4分钟

Snipaste_2022-12-23_15-23-52.png


什么是数据结构?

数据结构的定义:计算机中存储和组织数据的方式,通常选择好的数据结构可以带来最优效率的算法。

下面以三个例子来看

例1:如何在书架上摆放图书?

类比到计算机世界就是数据在存储空间中如何存放数据

图书的摆放要解决两个问题:、

  1. 新书如何插入
  2. 如何找到指定的书

实现的方法很多:

  1. 随便放--好放但是难找
  2. 按书名的拼音排序放--好找但是难放--每次都得把好多书都移动
  3. 先分类,在按书名的排序放--如何划分空间,如何分类

解决问题的效率,和数据的组织方式有关

例2:输入N,输出1-N的数字序列

这里使用了两种方法,循环和递归

#include<stdio.h>//循环
void printN1(int N) {
    for (int i = 0; i <= N; i++)
        printf("%d ", i);
}
//递归
void printN2(int N) {
    if (N) {
        printN2(N - 1);
        printf("%d ", N);
    }
}
int main() {
    int a = 0;
    scanf_s("%d", &a);
    printN1(a);
    //printN2(a);
    return 0;
}

其中递归的方法可能便于理解,但是其占用的内存空间可能很恐怖,进而导致程序异常终止

解决问题的效率,和空间的利用效率有关

例3:计算给定多项式在x点的值

//直接计算
double f(int n, double a[], double x) {
    int i;
    double p = a[0];
    for ( i = 0; i <= n ; i++)
    {
        p += (a[i] * pow(x,i))
    }
    return p;
}
//秦九邵算法
double f1(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;
}

对于上述的两个方法,我们想比较其运行的速度

#include<stdio.h>
#include<time.h>clock_t start,stop;
​
double duration;
​
int main(){
    //准备工作写在开始之前
​
    start = clock(); //开始计时
    f();//测试函数,需要计时的一系列操作
    stop = clock();//结束计时
    //clock():捕捉程序运行到该行的时间
    //CLK_TCK:机器时钟每秒走的时钟打点数
    duration = (double)(stop - start)/CLK_TCK; //计算时间
    
    //不在测试范围的处理写在其中
    return 0;
}
​
//注释:这里的计时程序可能输出的结果是0,因为运行太快,无法捕捉
//多次运行程序,让其累计一个时间段,就可以比较出来

解决问题的效率,和算法的巧妙程度有关

所以什么是数据结构

  1. 数据对象在计算机中的组织方式

    1. 逻辑结构

      1. 线性结构 一对一
      2. 树形结构 一对多
      3. 图形结构 多对多
    2. 物理存储结构:在机器的存放方式

      1. 数组
      2. 链表
    3. 抽象数据类型:通常用于描述数据结构

      1. 抽象:

        1. 与存放数据的机器无关
        2. 与数据存储的物理结构无关
        3. 与实现操作的算法和编程语言无关
        4. 只描述是什么,不关心如何做到
      2. 数据类型:在比较高级的程序语言中,这就是一个类

        1. 对象
        2. 操作:完成操作的方法就是算法

举例来理解抽象:

对于矩阵,不在乎其如何实现,其具体的数据类型是什么,不在乎用什么语言实现

Snipaste_2022-12-23_16-50-21.png

思考:为什么要抽象?抽象有什么好处?

我的理解:抽象可以方便的解决某一类共性问题


什么是算法?

  1. 一个有限的指令集

    1. 每一条指令有明确的目标,不能有歧义
    2. 计算机能处理的范围之内
    3. 描述的手段应该抽象
  2. 接受输入

  3. 至少产生一个输出

  4. 有限步骤

什么是好的算法?

时间复杂度和空间复杂度都要低

空间复杂度S(n):算法写成的程序在执行时占用的存储单元的长度

  1. 往往与输入的规模有关
  2. 复杂度过高算法可能会内存超限,导致程序异常中断

空间复杂度T(n):算法写成的程序在执行时所耗费时间的长度

  1. 常常与输入的规模有关
  2. 复杂度过高可能永远等不到结果

在分析一般算法的效率时,常常关注最坏情况复杂度

我们关心随着数据规模逐渐增大(当n充分大的时候),算法的复杂度如何增长

复杂度的渐进表示法:取最大下界和最小上界

Snipaste_2022-12-23_17-52-56.png

可以看到2的n次方以上,一个很小的输入最后的输出规模就很大

复杂度分析:多写算法多练吧