聊聊数据结构和算法

365 阅读5分钟

数据结构和算法在我们日常开发业务代码时,使用到的场景并不多。很多程序员职业生涯可能从来都没有涉及过,但是这却是很多面试都必考的环节,所以这成为了很多程序员心中的痛点问题。

一、为何要学习数据结构和算法

数据结构和算法虽然用到的场景并不多,但它却是程序员基础能力很重要的体现。自己当初学习的原因有如下几点:

  1. 面试需要,尤其是大厂面试,都喜欢考察算法,让人现场写代码。
  2. 想要挑战自己,成为更专业的人员。很多底层的框架不需要自己实现,并不代表什么都不需要了解。
  3. 对编程还有追求,不想被行业淘汰。这其中性能好坏就是其中一个非常重要的评判标准。

二、算法效率的评估标准

算法执行的效率主要通过复杂度的分析来评估。这其中就包括时间复杂度和空间复杂度,现在计算机内存也不值钱配置的容量越来越高,空间复杂度其实并不是什么大的问题,下面主要分析下算法的时间复杂度。

算法时间复杂度的计算方式一般使用大O时间复杂度表示法,它并不具体表示代码真正的执行时间,而是表示代码执行时间随数据规模增长的变化趋势,也叫做渐进时间复杂度。

常见的时间复杂度包含如下(按数量级递增):

image.png

image.png

三、常见的数据结构和算法

对于计算机来说存储在内存中的数据要么连续,要么非连续,其实也就只存在数组和链表两种存储结构。其它所有的数据结构都是逻辑上的概念,建立在数组和链表的基础之上。

3.1 数组

一种线性表数据结构。它用一组连续的内存空间,来存储一组具有相同类型的数据。

线性表:表示数据排成像一条线一样的结构。每个线性表上的数据最多只有前和后两个方向。数组、链表、队列、栈等也都是线性表结构。 image.png 非线性表:数据并不是简单的前后关系。如二叉树、堆、图等 image.png

数组在内存中属于一个连续存储区域,查找的效率是比较高的。但是插入和删除都会影响后续的连续数据,所以时间复杂度都是O(n)

3.2 链表

链表,并不需要一块连续的内存空间,通过“指针”将一组零散的内存块串联起来使用。 image.png

单链表 image.png

双向链表 image.png

循环链表 image.png

时间复杂度数组链表
插入、删除O(n)O(1)
随机访问O(1)O(n)

其它数据结构都是在数组和链表的其中进行包装,而衍生出来的逻辑概念,如散列表

散列表:用的是数组支持按照下表随机访问数据的特性,所以散列表其实就是数组的一种扩展,由数组演化而来。如果没有数组,就没有散列表。

image.png

3.3 数组结构和算法列表

数据结构:数组、链表、栈、队列、跳表、散列表、二叉树、红黑树、递归数、堆、图、Trie树等等

算法:递归、排序、二分查找、哈希算法、深度优先搜索、广度优先搜索、BM算法、贪心算法、分治算法、回溯算法、动态规划算法等等

四、数据结构和算法使用场景

4.1 浏览器前进后退的功能

  1. 使用两个栈X和Y
  2. 首次浏览的页面依次push->栈X
  3. 点击后退时,依次从栈X -> pop, push -> 栈Y
  4. 点击前进时,依次从栈Y -> pop, push -> 栈X
  5. 栈X无数据,说明不能继续后退
  6. 栈Y无数据,说明不能继续前进

4.2 如何根据年龄给100万用户排序

  1. 假设年龄的范围最小1岁、最大不超过120岁
  2. 可以遍历100万用户,根据年龄将其划分到120个桶里
  3. 依次顺序遍历这120个桶中的元素
  4. 这样就得到了按照年龄排序的100万用户数据

4.3 Word文档中单词拼写检查功能如何实现

  1. 常用英文单词大概20万左右,平均长度是10个字母,20万英文单词大约占2MB存储空间
  2. 可以使用散列表存储整个英文单词词典
  3. 当用户输入某个英文单词时,能够在O(1)时间复杂度就查找到单词。

需要结合数据结构和算法的场景是非常之多的,上面仅仅举了几个简单的示例,表示我们日常工作和生活中其实都是会遇到,只是我们可能未注意。

五、小结

数据结构和算法、与操作系统,计算机网格一样,都是比较偏底层的知识。你基本上也没有速成的办法,需要你沉下心来不停的思考和练习,才有可能融汇贯通成为你掌握的智慧。

生活前进的动力来源于你还有求知的欲望、好奇的冲动,你认为人生还有各种可能,而不是一尘不变。