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

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

一.什么是数据结构

关于什么是数据结构,官方没有统一的定义,陈越老师对于这个问题列举了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(在线处理)

在这里插入图片描述

四.常见数据结构

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

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

相关文章
|
8天前
|
存储 人工智能 算法
数据结构与算法细节篇之最短路径问题:Dijkstra和Floyd算法详细描述,java语言实现。
这篇文章详细介绍了Dijkstra和Floyd算法,这两种算法分别用于解决单源和多源最短路径问题,并且提供了Java语言的实现代码。
34 3
数据结构与算法细节篇之最短路径问题:Dijkstra和Floyd算法详细描述,java语言实现。
|
11天前
|
存储 算法
数据结构与算法学习二二:图的学习、图的概念、图的深度和广度优先遍历
这篇文章详细介绍了图的概念、表示方式以及深度优先遍历和广度优先遍历的算法实现。
27 1
数据结构与算法学习二二:图的学习、图的概念、图的深度和广度优先遍历
|
8天前
|
缓存 算法 Java
JVM知识体系学习六:JVM垃圾是什么、GC常用垃圾清除算法、堆内存逻辑分区、栈上分配、对象何时进入老年代、有关老年代新生代的两个问题、常见的垃圾回收器、CMS
这篇文章详细介绍了Java虚拟机(JVM)中的垃圾回收机制,包括垃圾的定义、垃圾回收算法、堆内存的逻辑分区、对象的内存分配和回收过程,以及不同垃圾回收器的工作原理和参数设置。
29 4
JVM知识体系学习六:JVM垃圾是什么、GC常用垃圾清除算法、堆内存逻辑分区、栈上分配、对象何时进入老年代、有关老年代新生代的两个问题、常见的垃圾回收器、CMS
|
9天前
|
算法
动态规划算法学习三:0-1背包问题
这篇文章是关于0-1背包问题的动态规划算法详解,包括问题描述、解决步骤、最优子结构性质、状态表示和递推方程、算法设计与分析、计算最优值、算法实现以及对算法缺点的思考。
32 2
动态规划算法学习三:0-1背包问题
|
4天前
|
存储 算法 Java
Set接口及其主要实现类(如HashSet、TreeSet)如何通过特定数据结构和算法确保元素唯一性
Java Set因其“无重复”特性在集合框架中独树一帜。本文解析了Set接口及其主要实现类(如HashSet、TreeSet)如何通过特定数据结构和算法确保元素唯一性,并提供了最佳实践建议,包括选择合适的Set实现类和正确实现自定义对象的hashCode()与equals()方法。
17 4
|
9天前
|
算法
动态规划算法学习四:最大上升子序列问题(LIS:Longest Increasing Subsequence)
这篇文章介绍了动态规划算法中解决最大上升子序列问题(LIS)的方法,包括问题的描述、动态规划的步骤、状态表示、递推方程、计算最优值以及优化方法,如非动态规划的二分法。
37 0
动态规划算法学习四:最大上升子序列问题(LIS:Longest Increasing Subsequence)
|
9天前
|
算法
动态规划算法学习二:最长公共子序列
这篇文章介绍了如何使用动态规划算法解决最长公共子序列(LCS)问题,包括问题描述、最优子结构性质、状态表示、状态递归方程、计算最优值的方法,以及具体的代码实现。
40 0
动态规划算法学习二:最长公共子序列
|
9天前
|
缓存 负载均衡 算法
nginx学习:配置文件详解,负载均衡三种算法学习,上接nginx实操篇
Nginx 是一款高性能的 HTTP 和反向代理服务器,也是一个通用的 TCP/UDP 代理服务器,以及一个邮件代理服务器和通用的 HTTP 缓存服务器。
17 0
nginx学习:配置文件详解,负载均衡三种算法学习,上接nginx实操篇
|
11天前
|
存储 算法 关系型数据库
数据结构与算法学习二一:多路查找树、二叉树与B树、2-3树、B+树、B*树。(本章为了解基本知识即可,不做代码学习)
这篇文章主要介绍了多路查找树的基本概念,包括二叉树的局限性、多叉树的优化、B树及其变体(如2-3树、B+树、B*树)的特点和应用,旨在帮助读者理解这些数据结构在文件系统和数据库系统中的重要性和效率。
13 0
数据结构与算法学习二一:多路查找树、二叉树与B树、2-3树、B+树、B*树。(本章为了解基本知识即可,不做代码学习)
|
11天前
|
存储 算法 数据管理
数据结构与算法学习二零:二叉排序树(BST)、平衡二叉树(AVL)
这篇文章通过需求分析、代码实现和测试验证,详细介绍了二叉排序树的创建、遍历和删除操作,以及二叉平衡树(AVL)的自平衡特性和单旋转操作,旨在提高树结构在数据管理中的效率和性能。
17 0
数据结构与算法学习二零:二叉排序树(BST)、平衡二叉树(AVL)