数据结构与算法 | 青训营笔记

51 阅读3分钟

数据结构与算法的用处

  1. 提高编程技能
  2. 优化程序性能
  3. 帮助解决实际问题

数据结构与算法几乎存在于程序开发中的所有地方。

经典排序算法

1. 插入排序

插入排序实际上就是在有序的数据中找到属于你自己的位置。
基本思想: 将一个记录插入到一个有序表中。

生活中有许多插入排序的例子。例如:打扑克牌,我们正常人的思路都是:

第一张牌其实已经有序,所以不需要再排。当拿到第二张牌的时候,就开始比较。正常来讲拿在我们手上的牌是不动的,那么我们需要决定这个第二张牌的位置,放前面还是后面。当第二张牌大,放后面,反之,放前面。当拿到第三张牌的时候,其实我们肉眼以及大脑是可以瞬间分析出来他的位置。但分析很简单。我们从最前面看到最后面,每个和第三张牌比较一下,然后具体的位置才有了。以此类推……

插入排序的算法实现过程:

image.png 由图可得,每次取一个数,这个数和前一位进行比较,比前一个data,交换,一直比,一直交换,直到前一个数比他大或者到第一个数了,结束比较和交换。

时间复杂度取决于数据本身的有序性:

image.png

如果数据基本有序,意味着O(n).因为每次和最后一次比较时,发现比他大,然后结束比较直接进入下一个数的比较,一共比较n次。则 n × 1 为 n 次。因此O(n)

如果数据反序,那么,第一次要比较1 次,第二次比较2次,第三次比较3次,因此时间复杂度时n x (1+n)/2,因此是O(n2)。

其他情况介于这两个之间。

2. 快速排序

经典的 快速排序(quicksort) 主要采用了分治的思想,具体的过程是将一个 array 通过选定一个 pivot(锚点)分成不同的 sub-arrays,选定 pivot 后,使得这个 array 中位于 pivot 左边的元素都小于 pivot,位于 pivot 右边的元素都大于 pivot。由此,pivot 两边构成了两个 sub-arrays,然后对这些 sub-arrays 进行相同的操作(选定 pivot 然后切分)。当某个 sub-array 只有一个元素时,其本身有序,此时便可以退出循环。如此反复,最后得到整体的有序。

我们可以观察到,经典的 quicksort 主要过程就是两步:

  • choose pivot: 选择一个 pivot
  • partition: 使用 pivot 对 array 进行划分

总的来说,quicksort 的性能关键点在于选定 pivot,选择 pivot 的好坏直接决定了排序的速度,如果每次 pivot 都被选定为真正的 median(中位数),此时快排的效率是最高的。因此 pivot 的选择重点在于寻找 array 真正的 median,目前所有的 pivot 选择方案都是在寻找一个近似的 median。

image.png