数据结构之Sort Algorithm
最近开始学习数据结构的内容,在udemy上学完了一门Java数据结构和算法的课程。因为之前也没有接触过Java,所以就只当作数据结构的原理课来上,接下来所有的介绍也是着重介绍原理。
写这篇文章的主要目的是督促自己梳理总结学过的知识,促进理解,同时也希望能帮助到需要了解相关知识的同学。
首先是数据结构和算法这两个基本定义的介绍。
数据结构,可以简单理解为数据被组织储存起来的方式。本系列会介绍的数据结构分别有 Array,Stack, Queue, Hashtable, Tree, Heap以及Set。
现在无论是在统计学或者是机器学习领域,大家都十分热衷于讨论算法。那么算法究竟是什么呢?通俗一点讲,算法就是完成一个特定任务的说明书,说明书里面会按照合理的顺序, 详尽地描述完成任务所需的步骤。
接下来介绍第一个基本的数据结构:Array。相信只要接触过编程语言的同学, (例如Python,Java等), 对Array都不会感到陌生。Array有四个区别于其他数据结构的特质,分别是:(1)Array中的所有元素在Memory中都是以连续的形式储存的。假如将Memory比喻成一个书柜,而Array是一套系列丛书,你要将这套系列丛书放到书柜上,肯定是将他们放在一个位置上,不可能硬生生拆开分开放的。(2)Array中的每一个元素在Memory中都占据一样的空间。也就是说,即使Array中的某一个元素看起来似乎比另一个元素需要更多的储存空间,他们占据的储存空间也必须是相同的。(3)Array中的元素在储存空间中的位置非常好确定。只要你知道某个Array的第一个元素在Memory中的位置,那么你就可以很轻易地推断出其他任何一个元素在Memory中的位置,因为Array的每个元素都是以连续的形式储存在Memory中。(4)假设知道目标元素在Array中的具体位置(即Index)在Array中提取元素的time complexity是O(1),即常数级的time complexity; 假设不知道目标元素的具体位置,那么提取此元素的time complexity为O(N), 即线性级的time complexity。
为了避免部分同学事先不知道time complexity这个概念,我在这简单介绍一下什么是time complexity(下文翻译成 耗时)。耗时,指的并不是真正意义上的用时长短,而是指实现某算法需要完成的步骤的多少,或是需要占据的储存空间的大小。现在储存空间的大小限制已经不是一个什么问题了,因为现在你可以用很低的成本去获取非常大的储存空间。所以,现在说的耗时,更多的是指实现某算法需要完成的步骤的多少。假设现在有一个泡茶算法,步骤分别如下:(1)取茶包(2)将茶包放入杯中 (3)将100ml热水倒入杯中 (4)当杯子七分满时,停止倒水(杯子容量是1000ml)。这个时候,当你实现这个泡茶算法时,你需要按顺序完成步骤(1)、(2)、(3),并重复步骤(3)直至满足算法终止条件为止,即杯子七分满时。也就是说你需要完成(2+17)个步骤。假设这个杯子跟一个房子一样大,那么你需要完成(2 + 1n)个步骤,n会取一个非常大的值,2可以忽略不计,那么这就是一个线性耗时,通常记为O(N)。通常还有常数级耗时O©,对数级耗时O(logN),平方级耗时O(N2)等。这些耗时按效率由高往低排分别是:O© > O(N) > O(logN) > O(N2)。耗时这个概念非常重要,往往会成为衡量