一、数据结构
一种线性表结构,连续的内存空间存储相同数据类型的数据。
说到线性表,有必要列出一下:
名称 | 种类 |
线性表 | 数组、链表、队列、栈 |
非线性表 | 二叉树、堆、图 |
数组最大的优势是:可以通过下标随机访问,时间复杂度为O(1)(由于线性的,且内存空间连续)。
数组劣势是:删除和插入比较费劲,时间复杂度为O(n)(需要移动删除和插入元素后的所有元素)。
STL中的vector(动态数组)在业务可以直接拿来使用。vector的size和capacity有什么区别?
2.链表
链表经常和数组进行比较,数组在内存分配的时候要求比较苛刻,必须需要连续一块内存空间;而链表则不需要,链表(单链表)的数据结构里定义了一个next指针,用这个指针把所有的结点都连接起来,所以链表就可以利用自身的优势把内存分散的内存片利用起来,进而没有分配大小的限制(内存空间够用的情况下)。
链表的最大优势是:删除和插入时间复杂度为O(1);注意:这里指的是插入和删除指定位置,如果操作的位置还需要查找,查找的时间复杂度就为O(n)。
链表的劣势是:不能像数组那样随机访问,查找时间复杂度为O(n)。
单链表的定义:
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
双向链表能O(1)的时间复杂度找到前驱结点,在删除和查找方面起到很重要的作用。
双向链表的定义:
struct ListNode {
int val;
ListNode *pre;
ListNode *next;
ListNode(int x) : val(x), pre(NULL), next(NULL) {}
};
循环链表是在上面两种链表上形成一个环。
链表编程练习:链表
3.栈
栈特点是:先进后出,只能从一端(栈顶)插入(push)和弹出(pop)。
栈的应用场景:函数的调用(用栈来保存临时变量,在函数递归时表现的尤为突出)、比如浏览器的前进后退功能。
栈可用数组(顺序栈)和链表(链式栈)实现。
4.队列
队列和栈经常放在一起作对比,队列是先进先出,从队列的尾入队(push),从队列的头出队(pop)。
队列可用数组(顺序队列)和链表(链式队列)实现。
在线程池上的应用。
5.散列表
通过散列函数将值(value)映射到键值(key),通过这种value=hash(key)的对应关系,能够快速的查找到集合中的该元素。最简单的就是数组,数组就是通过下标和值建立对应关系,才使查询元素的时间复杂度为O(1)。
散列表还有个问题,就是冲突的问题,怎么解决呢?
散列应用场景:快速查找,或者检测元素在不在集合里。
思考题1:有10万条访问URL的日志,怎么按访问次数给URL排序?
解法:第一步,统计 hash(URL) = count,即URL作为key,访问次数count作为value;第二步,按照value(即count)排序。
思考题2:有两个10万大小的字符串数组,怎么找出两个数组相同的字符串?
解法:第一步,给第一个数组的字符串做哈希, hash(str) = count,即str作为key,出现次数count作为value;第二步,从第二个数组拿出字符串,去建立好的哈希表里查找,如果value > 0,则说明该字符串在第一个数组已经出现过。
另外,哈希算法(散列只是哈希算法的一种应用)的应用不止这些,还有:校验(MD5、SHA1、SHA256),一致哈希(分布式集群的应用)
6.二叉树
树的属性:
二叉树的类型:
二叉树的遍历:二叉树
二叉查找树:任意一个节点,左子树的值小于该节点的值,而右子树大于该节点的值。
二叉查找树也经常拿来和散列表比较,(1)虽然散列表的插入、删除和查找都能做到O(1)级别的时间复杂度,而要得到有序的序列,就必须去排序,而二叉查找树的中序遍历可以得到有序的序列(O(n)时间复杂度就可以得到有序序列);(2)散列经常面临冲突的问题,构造哈希函数比较复杂,以至于散列不是很友好,反而二叉查找树插入、删除和查找的时间复杂度能够稳定在O(logn)级别。
二叉查找树最坏的情况下会退化为链表,所以要求树的任意左右子树高度差不能超过1,从定义看满二叉树、完全二叉树满足的平衡的条件,但并不是查找树,平衡二叉查找树就是在二叉查找树基础上再要求平衡。红黑树就是广泛应用的AVL。
二叉查找树的查找和插入比较简单,删除稍有点复杂。代码实现:
7.堆
堆的定义:(1)堆是完全二叉树;(2)堆的节点值必须都大于(或小于)其子树的值(这点和二叉查找树要区别开来)。
堆的应用:优先队列
代码实现:建堆、插入、删除、排序
8.跳表
跳表在redis中的应用,是因为跳表能够进行区间查找。
9.图
10.Trie树(字典树)
字典树的应用:自动补全功能(输入法不全、写代码自动补全、搜索引擎输入字符自动补全)
二、算法