数据结构与算法分析

Python数据结构与算法分析(笔记与部分作业)

与世无争的帅哥 提交于 2020-03-16 03:40:50
最近为了给写搬砖脚本增加一些算法知识,脑残的看起来算法书。Python数据结构与算法分析,本人英语比较差,看的是翻译版本的。 网上有免费的原版的:https://runestone.academy/runestone/books/published/pythonds/index.html 不废话,开笔记,第一章Python基础,最后的反向思路就稍微卡住了我一下。 第1章,导论 计算机科学的研究对象是问题、解决问题的过程,以及通过该过程得到的解决方案。算法就是解决方案。 计算机科学可以定义为:研究问题及其解决方案,以及研究目前无解的问题的科学。 编程是指通过编程语言将算法编码以使其能被计算机执行的过程。如果没有算法,就不会有程序。 Python支持面向对象编程范式。这意味着Python认为数据是问题解决过程中的关键点。在Python以及其他所有面向对象编程语言中,类都是对数据的构成(状态)以及 数据能做什么(行为)的描述。由于类的使用者只能看到数据项的状态和行为,因此类与抽象数据类型相似的。 在面向对象编程范式中,数据项被称为对象。一个对象就是类的一个实例。 上两个书中的完整代码: def gcd(m,n): while m%n != 0: oldm = m oldn = n m = oldn n = oldm%oldn return n class Fraction: def _

数据结构与算法分析:(五)循环链表

自闭症网瘾萝莉.ら 提交于 2020-02-29 02:05:50
一、前言 相信小伙伴们在前面两篇文章的详细介绍已经对单向链表、双向链表有一个很清晰的认识了。 数据结构与算法分析:(三)单向链表 数据结构与算法分析:(四)双向链表 接下来我们来介绍循环链表,你把单向链表、双向链表搞清楚了的话,循环链表自然也不难了。 循环链表可分为:单向循环链表、双向循环链表。 1、单向循环链表: 单向循环链表跟单向链表唯一的区别就在 尾结点 。我们知道,单向链表的尾结点指针指向空地址,表示这就是最后的结点了。而单向循环链表的尾结点指针是指向链表的头结点。从我画的单向循环链表图中,你应该可以看出来,它像一个环一样首尾相连,所以叫作“单向循环”链表。 和单向链表相比,单向循环链表的优点是从链尾到链头比较方便。当要处理的数据具有环型结构特点时,就特别适合采用单向循环链表。比如著名的 约瑟夫问题 。尽管用单向链表也可以实现,但是用单向循环链表实现的话,代码就会简洁很多。 2、双向循环链表: 双向循环链表想必也不用我多说了吧。 二、循环链表实战 假设有这么一个小游戏: 100个人围成圆圈,从1开始报数,喊到3人的时候退出,重复,直到剩下最后一个人。 看到围成圆圈,立马想到了 循环链表 这个数据结构。 1、我们先来定义循环链表的接口 public interface CircularLinkedList < E > { /** * 向链表插入一个元素,默认在尾部 *

数据结构与算法分析:(三)链表(上)

让人想犯罪 __ 提交于 2020-02-24 13:54:32
一、什么是链表? 链表是一种物理上 非连续 、 非顺序 的存储结构,数据元素之间的顺序是通过每个元素的 指针 (类似C语言中的指针,Java中是引用)关联的。 链表由一系列节点组成,每个节点一般至少会包含两部分信息:一部分是元素数据本身,另一部分是指向下一个元素地址的“指针”。这样的存储结构让链表相比其他线性的数据结构来说,操作会复杂一些。 说到链表,我们经常拿来与数组比。我们先看下面一张图再来对比它们的各自的优劣。 从图中我们看到,数组需要一块 连续 的内存空间来存储,对内存的要求比较高。如果我们申请一个 100MB 大小的数组,当内存中没有连续的、足够大的存储空间时,即便内存的剩余总可用空间大于 100MB,仍然会申请失败。 而链表恰恰相反,它并不需要一块连续的内存空间,它通过“指针”将一组零散的内存块串联起来使用,所以如果我们申请的是 100MB 大小的链表,根本不会有问题。 这里先思考一下下面这个问题。 Q:数组在实现上为什么使用的是连续的内存空间? A:可以借助 CPU 的缓存机制,预读数组中的数据,所以访问效率更高。而链表在内存中并不是连续存储,所以对 CPU 缓存不友好,没办法有效预读。 Q:上一答案中CPU缓存机制指的是什么?为什么就数组更好了? A: CPU在从内存读取数据的时候,会先把读取到的数据加载到CPU的缓存中

十大经典排序算法

青春壹個敷衍的年華 提交于 2019-12-21 02:53:29
转自https://blog.csdn.net/hellozhxy/article/details/79911867 0、排序算法说明0.1 排序的定义 对一序列对象根据某个关键字进行排序。 0.2 术语说明 稳定:如果a原本在b前面,而a=b,排序之后a仍然在b的前面; 不稳定:如果a原本在b的前面,而a=b,排序之后a可能会出现在b的后面; 内排序:所有排序操作都在内存中完成; 外排序:由于数据太大,因此把数据放在磁盘中,而排序通过磁盘和内存的数据传输才能进行; 时间复杂度: 一个算法执行所耗费的时间。 空间复杂度:运行完一个程序所需内存的大小。 例子 数据量低时,O(1) 和 O(n^2)的区别可以忽略不计。比如,你有个算法要处理2000条元素。 O(1) 算法会消耗 1 次运算 O(log(n)) 算法会消耗 7 次运算 O(n) 算法会消耗 2000 次运算 O(n*log(n)) 算法会消耗 14,000 次运算 O(n^2) 算法会消耗 4,000,000 次运算 O(1) 和 O(n^2) 的区别似乎很大(4百万),但你最多损失 2 毫秒,只是一眨眼的功夫。确实,当今处理器每秒可处理上亿次的运算。这就是为什么性能和优化在很多IT项目中不是问题。 我说过,面临海量数据的时候,了解这个概念依然很重要。如果这一次算法需要处理 1,000,000 条元素

《数据结构与算法分析》——C语言描述 第二版 学习笔记一

杀马特。学长 韩版系。学妹 提交于 2019-12-07 04:46:07
《数据结构与算法分析》——C语言描述 第二版 第一章 引论 第二章 算法分析 一、基本数学知识 指数、对数、级数、同余、模运算、数据结构分析中的反证法和归纳法、调和数列、欧拉常数。 二、递归简论 int F( int X ) { if ( X == 0 ) return 0 ; //基准情形 else return 2 * F ( X - 1 ) + X * X ; //不断推进 } 递归的四个基本准则: 基本情形 :不需要递归就可以求解的情况; 不断推进 :对于需要递归求解的情形, 递归调用总是向着产生基准情形的方向推进 ; 设计法则 :假设所有的递归都能运行; 合成效益法则 :切勿在不同递归中做重复性的工作。 (未完待续) 2019.03.03 数据结构学习 ZaneLing 来源: CSDN 作者: ZaneLing 链接: https://blog.csdn.net/weixin_37684179/article/details/88087326

数据结构与算法分析第一章引论

佐手、 提交于 2019-12-05 12:44:54
第一章引论 引论中心思想 : 1、在合理的时间内能够处理较大的数据量,才是一个切合实际的算法。 2、写出一个可以工作的程序并不够,如果在巨大数据集上运行,那么运行时间也成了重要问题。 所以学习算法的目之一:对于大量的输入,估计程序的运行时间,在尚未 具体编码的情况下比较两个程序的运行时间。并且改进程序的速度,确定程序瓶颈的方法 补:后面还会看到,如果输入量不大,而过多设计也是得不偿失的,不过不在算法讨论范围内,那可能叫做过度设计 引论中提出的数学概念 : 几何级数: 几何级数是一个数学上的概念,可以表示成 ,即x的y次方的形式增长,又叫等比级数。 算术级数:又称等差级数 斐波那契数:F(0)=1,F(1)=1, F(n)=F(n-1)+F(n-2)(n>=2,n∈N*) 可证明F(K+1)< (5/3)^(K+1) 数学归纳法:...... 如果N整除A-B,那么我们就说A与B模同余。无论A还是B被N去除,所得余数都是相同的。 递归简论 : 递归的定义:当一个函数用它自己来定义时就称为是递归的。 C提供的仅仅是遵循递归思想的一种企图,不是所有的数学递归函数都能有效的由C的递归模拟来实现。 对于数值计算使用递归通常不是好主意。 递归的基本法则: 1.基准情况 2.不断推进 3.设计法则 4.合成效益法则:在求解一个问题的同一实例,切勿在不同的递归调用中做重复性的工作。

数据结构与算法分析--单链表

匿名 (未验证) 提交于 2019-12-03 00:10:02
头结点:单链表前面附设的一个结点 头指针:从头指针开始,指向第一个结点的指针 首节点:第一个包含元素的结点 单链表的存储结构: typedef struct Node { ElemType data ; struct Node * next ; } Node ; typedef struct Node * LinkList ; //定义LinkList 单链表的读取实现: /*获得链表第i个数据 操作结果:用e返回L中第i个元素的值*/ Status GetElem ( LinkList L , int i , ElemType * e ){ int j ; LinkList p ; //声明一个结点p p = L -> next ; //让p指向链表的第一个结点 j = 1 ; //j为计数器 while ( p && j < i ){ //*p不为空或者计数器j没有等于i时,循环继续 p = p -> next ; //p指向下一个结点 ++ j ; } if (! p || j > i ) return ERROR ; //第i个元素不存在 * e = p -> data ; //取第i个元素的数据 return OK ; } 单链表的插入实现: // 两步实现 s -> next = p -> next ; p -> next = s ; /*初始条件:顺序表已经存在,

十大经典排序算法

无人久伴 提交于 2019-11-28 19:59:43
排序概念 对一序列对象根据某个关键字进行排序。 算法总结 名词解释: n: 数据规模 k: “桶”的个数 In-place: 占用常数内存,不占用额外内存 Out-place: 占用额外内存 专业术语: 稳定:如果a原本在b前面,而a=b,排序之后a仍然在b的前面; 不稳定:如果a原本在b的前面,而a=b,排序之后a可能会出现在b的后面; 内排序:所有排序操作都在内存中完成; 外排序:由于数据太大,因此把数据放在磁盘中,而排序通过磁盘和内存的数据传输才能进行; 时间复杂度: 一个算法执行所耗费的时间。 空间复杂度:运行完一个程序所需内存的大小。 算法分类 比较和非比较的区别 常见的 快速排序、归并排序、堆排序、冒泡排序 等属于 比较排序 。 在排序的最终结果里,元素之间的次序依赖于它们之间的比较。每个数都必须和其他数进行比较,才能确定自己的位置。 在 冒泡排序 之类的排序中,问题规模为n,又因为需要比较n次,所以平均时间复杂度为O(n²)。在 归并排序、快速排序 之类的排序中,问题规模通过 分治法 消减为logN次,所以时间复杂度平均 O(nlogn) 。 比较排序的优势是,适用于各种规模的数据,也不在乎数据的分布,都能进行排序。可以说, 比较排序适用于一切需要排序的情况。 计数排序、基数排序、桶排序 则属于 非比较排序 。非比较排序是通过确定每个元素之前,应该有多少个元素来排序

小白の数据结构与算法の自娱自乐(一)

可紊 提交于 2019-11-28 19:52:27
数据结构与算法分析 引论 数学公式 引论 数学公式 指数 对数 在计算机科学中,除非有特别的声明,所有的对数都是以 2 为底的。 级数 4. 模运算 5. 递归 的四个基本法则: (1)基准情形:你必须总要有某些基准的情形,它们不用递归就能求解。 (2)不断推进:对于那些需要递归求解的情形,递归调用必须总能够朝着基准情形的方向推进。 (3)设计法则:假设所有的递归调用都能运行。 (4)合成效益法则:在求解一个问题的同一实例时,切勿在不同的递归调用中做重复性的工作。 可以通过对字典查词进行理解,如果该字典能够该词解释中的所有单词,则成功,循环能够终止;否则,失败,循环不定。 来源: https://blog.csdn.net/qq_42875616/article/details/100120485

数据结构与算法分析(四)链表

一个人想着一个人 提交于 2019-11-27 15:18:02
一、什么是链表? 1.和数组一样,链表也是一种线性表。 2.从内存结构来看,链表的内存结构是不连续的内存空间,是将一组零散的内存块串联起来,从而进行数据存储的数据结构。 3.链表中的每一个内存块被称为节点Node。节点除了存储数据外,还需记录链上下一个节点的地址,即后继指针next。 二、为什么使用链表?即链表的特点 1.插入、删除数据效率高O(1)级别(只需更改指针指向即可),随机访问效率低O(n)级别(需要从链头至链尾进行遍历)。 2.和数组相比,内存空间消耗更大,因为每个存储数据的节点都需要额外的空间存储后继指针。 三、常用链表:单链表、循环链表和双向链表 1.单链表 1)每个节点只包含一个指针,即后继指针。 2)单链表有两个特殊的节点,即首节点和尾节点。为什么特殊?用首节点地址表示整条链表,尾节点的后继指针指向空地址null。 3)性能特点:插入和删除节点的时间复杂度为O(1),查找的时间复杂度为O(n)。 2.循环链表 1)除了尾节点的后继指针指向首节点的地址外均与单链表一致。 2)适用于存储有循环特点的数据,比如约瑟夫问题。 3.双向链表 1)节点除了存储数据外,还有两个指针分别指向前一个节点地址(前驱指针prev)和下一个节点地址(后继指针next)。 2)首节点的前驱指针prev和尾节点的后继指针均指向空地址。 3)性能特点: 和单链表相比,存储相同的数据