数据结构与算法-浙江大学陈越数据结构第一章学习

简介: 数据结构与算法-浙江大学陈越数据结构第一章学习

一.什么是数据结构

关于什么是数据结构,官方没有统一的定义,陈越老师对于这个问题列举了3个(sartaj sahni,Clifford A.Shaffer,中文维基百科)描述,从中我们发现数据结构和算法息息相关。
在这里插入图片描述
然后陈越老师列举了以下3个例子,来理解数据结构。
例1:如何在书架上摆放图书?
摆放图书的操作:

  • 新书怎么插入
  • 怎么找到某本指定图书

摆放图书的方法:

  • 随便摆放(插入方便,当插入的图书数量较多时查找麻烦)
  • 按照书名的拼音字母顺序排放(插入比较方便,查找比较方便)
  • 把书架划分成几块区域,每块区域指定摆放某种类别的图书;在每种类别内,按照书名的拼音字母顺序排放(插入方便,查找方便,需要考虑类别划分,和空间分配问题)

从上面的例子我们可知:

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

例2:写程序实现一个函数PrintN,使得传入一个正整数为N的参数后,能顺序打印从1到N的全部正整数。
通过循环实现:
在这里插入图片描述
运行效果:
在这里插入图片描述
通过递归实现:
在这里插入图片描述
运行效果:
在这里插入图片描述
每一个程序,存放临时数据存储空间是有限的(使用的临时数据存放到内存中),上面的程序,每迭代一次,就会多一个临时数据,就会占用一个临时空间,当占的存储空间超过程序使用的存储空间的时候,就会非正常退出,出现像上面那样,没有任何结果输出。
在这里插入图片描述

从上面的例子可知:

  • 解决问题方法的效率,跟空间的利用效率有关

在这里插入图片描述

c语言计时函数:
在这里插入图片描述
第一种求多项式方法: 通过f(x)=an X x^n^ 对每项求和
在这里插入图片描述
第二种求多项式方法: 秦九韶算法
在这里插入图片描述

具体代码:

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

clock_t start, stop; 
double duration;
double f1( int n, double a[], double x, int count);
double f2( int n, double a[], double x, int count);



int main (){
    double a[100];
    int i=0,count=10000000;
    for (i=0;i<10;i++){
        a[i]=i;
    }
    start = clock();
    // 被测函数
    f1(9,a,6,count);
    stop = clock();
    duration = ((double)(stop-start))/CLK_TCK/count;
    printf("第一种方法打点个数:%f\n",(double)(stop-start));
    printf("第一种方法运行时间:%6.2e\n",duration);
    
    start = clock();
    // 被测函数
    f2(9,a,6,count);
    stop = clock();
    duration = ((double)(stop-start))/CLK_TCK/count;
    printf("第二种方法打点个数:%f\n",(double)(stop-start));
    printf("第二种方法运行时间:%6.2e\n",duration);
    return 0; 
}

double f1( int n, double a[], double x,int count)
{
    int i;
    double p = a[0];
    while(count!=0){
        --count;
        for ( i=1; i<=n; i++){
            p += (a[i] * pow(x,i));
        }    
    }
    
    return p;
}

double f2( int n, double a[], double x,int count)
{
    int i;
    double p = a[0];
    while(count!=0){
        --count;
            for ( i=n; i>0; i--){
                p += a[i-1] + x*p;
            }    
    }
    
    return p;
}

运行效果:
在这里插入图片描述
从上面的例子我们可知:

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

通过上面的实例,再来思考上面的问题(什么是数据结构)?

  • 数据对象在计算机中的组织方式,分为逻辑结构(集合结构,线性结构,树形结构,图形结构)和物理结构(顺序存储和链式存储)
  • 数据对象必定与一系列加在其上的操作相关联
  • 完成这些操作所用的方法就是算法

备注:

  • 逻辑结构:是指数据对象中数据元素之间的相互关系。
  • 物理结构:是指数据的逻辑结构在计算机中的存储形式。

关于什么是抽象数据类型

  • 数据类型:是指一组性质相同的值的集合及定义在此集合上的一些操作的总称(在面向对象语言中叫做类)。
  • 抽象:是指抽取出事物具有的普遍性的本质。它是抽出问题的特征而忽略非本质的细节,是对具体事物的一个概括。抽象是一种思考问题的方式,它隐藏了繁杂的细节,只保留实现目标所必需的信息。
  • 抽象数据类型(Abstract Data Type,ADT):是指一个数学模型及定义在该模型上的一组操作。抽象数据类型的定义仅取决于它的一组逻辑特性,而与其在计算机内部如何表示和实现无关(只描述数据对象集和相关操作集“是什么”,并不涉及“如何做到”的问题)。

在这里插入图片描述
在这里插入图片描述

二.什么是算法

1.定义

在这里插入图片描述

2.什么是好算法

衡量算法的好坏由时间复杂度和空间复杂度决定,并不仅仅只是时间复杂度或空间复杂度一方越好该算法就越好,而是根据实际场景,选择时间复杂度和空间复杂度的一个平衡点,有的时候为了追求运行速度我们会相应的舍弃一些空间来换取时间(提高运行速度),或者为了减少使用的空间降低运行的速度。
在这里插入图片描述
复杂度分析:

  • T(N)= C·N

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.最坏情况复杂度与平均复杂度

  • 最坏情况运行时间是一种保证,那就是运行时间将不会再坏了。在应用中,这是一种最重要的需求,通常,除非特别指定,我们提到的运行时间都是最坏情况的运行时间。
  • 平均运行时间是所有情况中最有意义的,因为它是期望的运行时间。

在这里插入图片描述

4.复杂度的渐进表示法

(无需关心算法具体执行了多少次,只需要粗略地知道它的增长趋势即可)

  • 上界
  • 下界
  • 等价

在这里插入图片描述
大O()记法:用来体现算法时间复杂度
推导大O阶

  • 1.用常数1取代运行时间中的所有加法常数。
  • 2.在修改后的运行次数函数中,只保留最高阶项。
  • 3.如果最高阶项存在且不是1,则去除与这个项相乘的常数。

常数阶
以下代码的大O()表示为O(1)而不是O(3)=O(1+1+1)(由推导大O阶第1条可知)
在这里插入图片描述
同理以下代码的大O()表示为O(1)
在这里插入图片描述
事实上无论n为多少,上面的两段代码就是3次和12次执行的差异。这种与问
题的大小无关(n的多少),执行时间恒定的算法,我们称之为具有0(1)的时间复杂
度,又叫常数阶。
注意:不管这个常数是多少,我们都记作0(1),而不能是0(3)、 0(12)等其他任何数字,这是初学者常常犯的错误。

线性阶
线性阶的循环结构会复杂很多。要确定某个算法的阶次,我们常常需要确定某个特定语句或某个语句集运行的次数。因此,我们要分析算法的复杂度,关键就是要分
析循环结构的运行情况。
下面这段代码,它的循环的时间复杂度为0(n),因为循环体中的代码须要执行n次。

int i;
for(i=0;i<n;i++){
    /* 时间复杂度为O(1)的程序步骤序列
}

对数阶
在这里插入图片描述
平方阶
在这里插入图片描述

5.常见函数的输入规模

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
备注: 当我们编写的算法运行时间要大于nlogn的时候,我们尽量将该算法优化到nlogn。

6.复杂度分析小窍门

在这里插入图片描述

三.应用实例(最大子列和问题)

(1) 什么是最大子列和问题

在这里插入图片描述

(2) 算法1

在这里插入图片描述

(3) 算法2

在这里插入图片描述

(4) 算法3

4:4和-3二个数,不运算值为4,运算后值为1,所以最大为4
5:5和-2二个数,不运算值为5,运算后值为3,所以最大为5
6:4和-3(运算后1,不运算是4),4,-3和5(4和-3运算后为1再和5运算为6),4,-3,5,和-2(前面进行运算后为6如果再和-1运算就为5了,所以选择不运算为6),所以最大为6
在这里插入图片描述

(4) 算法4(在线处理)

在这里插入图片描述

四.常见数据结构

常用的数据结构可根据数据访问的特点分为线性结构和非线性结构。线性结构包括常见的链表、栈、队列等,非线性结构包括树、图等。
在这里插入图片描述

相关视频学习链接:
数据结构与算法基础(青岛大学-王卓)
在这里插入图片描述

相关文章
|
2月前
|
存储 算法 Go
算法学习:数组 vs 链表
算法学习:数组 vs 链表
33 0
|
2月前
|
机器学习/深度学习 算法 PyTorch
【从零开始学习深度学习】43. 算法优化之Adam算法【RMSProp算法与动量法的结合】介绍及其Pytorch实现
【从零开始学习深度学习】43. 算法优化之Adam算法【RMSProp算法与动量法的结合】介绍及其Pytorch实现
|
11天前
|
机器学习/深度学习 人工智能 资源调度
【博士每天一篇文献-算法】连续学习算法之HAT: Overcoming catastrophic forgetting with hard attention to the task
本文介绍了一种名为Hard Attention to the Task (HAT)的连续学习算法,通过学习几乎二值的注意力向量来克服灾难性遗忘问题,同时不影响当前任务的学习,并通过实验验证了其在减少遗忘方面的有效性。
28 12
|
3天前
|
算法 Java
掌握算法学习之字符串经典用法
文章总结了字符串在算法领域的经典用法,特别是通过双指针法来实现字符串的反转操作,并提供了LeetCode上相关题目的Java代码实现,强调了掌握这些技巧对于提升算法思维的重要性。
|
5天前
|
算法 NoSQL 中间件
go语言后端开发学习(六) ——基于雪花算法生成用户ID
本文介绍了分布式ID生成中的Snowflake(雪花)算法。为解决用户ID安全性与唯一性问题,Snowflake算法生成的ID具备全局唯一性、递增性、高可用性和高性能性等特点。64位ID由符号位(固定为0)、41位时间戳、10位标识位(含数据中心与机器ID)及12位序列号组成。面对ID重复风险,可通过预分配、动态或统一分配标识位解决。Go语言实现示例展示了如何使用第三方包`sonyflake`生成ID,确保不同节点产生的ID始终唯一。
go语言后端开发学习(六) ——基于雪花算法生成用户ID
|
11天前
|
存储 机器学习/深度学习 算法
【博士每天一篇文献-算法】连续学习算法之HNet:Continual learning with hypernetworks
本文提出了一种基于任务条件超网络(Hypernetworks)的持续学习模型,通过超网络生成目标网络权重并结合正则化技术减少灾难性遗忘,实现有效的任务顺序学习与长期记忆保持。
14 4
|
11天前
|
存储 机器学习/深度学习 算法
【博士每天一篇文献-算法】连续学习算法之RWalk:Riemannian Walk for Incremental Learning Understanding
RWalk算法是一种增量学习框架,通过结合EWC++和修改版的Path Integral算法,并采用不同的采样策略存储先前任务的代表性子集,以量化和平衡遗忘和固执,实现在学习新任务的同时保留旧任务的知识。
49 3
|
11天前
|
存储 机器学习/深度学习 算法
【博士每天一篇文献-综述】基于脑启发的连续学习算法有哪些?附思维导图
这篇博客文章总结了连续学习的分类,包括经典方法(重放、正则化和稀疏化方法)和脑启发方法(突触启发、双系统启发、睡眠启发和模块化启发方法),并讨论了它们在解决灾难性遗忘问题上的优势和局限性。
13 2
|
1月前
|
机器学习/深度学习 数据采集 算法
Python实现ISSA融合反向学习与Levy飞行策略的改进麻雀优化算法优化支持向量机回归模型(SVR算法)项目实战
Python实现ISSA融合反向学习与Levy飞行策略的改进麻雀优化算法优化支持向量机回归模型(SVR算法)项目实战
|
1月前
|
机器学习/深度学习 数据采集 算法
Python实现ISSA融合反向学习与Levy飞行策略的改进麻雀优化算法优化支持向量机分类模型(SVC算法)项目实战
Python实现ISSA融合反向学习与Levy飞行策略的改进麻雀优化算法优化支持向量机分类模型(SVC算法)项目实战

热门文章

最新文章