多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
### 概述 动态数组,栈,队列底层都是依托于静态数组,靠resize解决固定容量问题.而链表是真正的动态数据结构. * 链表是最简单的动态数据结构. * 更深入的理解引用(或者指针). * 更深入的理解递归. * 辅助组成其他数据结构 . ### 链表Linked list * 数据存储在"节点"(Node)中,当一个节点的next是NULL,那么这个节点就是最后一个节点. ![](https://box.kancloud.cn/38f33b7969b5acd730c12a3381eb13c7_1596x299.png) * 优点:真正的动态,不需要处理固定容量的问题.需要多少的数据,就生成多少个节点. * 缺点:丧失了随机访问的能力. ### 数组和链表的对比 #### 数组 * 数组对号用于索引有语意的情况 . scores[2] * 最大优点:支持快速查询. #### 链表 * 链表不适合用于索引有语意的情况. * 最大优点:动态. ### 向链表中添加元素 和数组不同,数组在尾部添加元素比较方便,而链表是在头部添加元素比较方便 . #### 在链表头添加元素 ![](https://box.kancloud.cn/b362418898c1aca4888187f8567f257d_1609x640.png) #### 为链表设立虚拟头结点 在向链表头添加元素和在链表其他位置添加元素逻辑上会有差别,为什么对链表头添加元素会有差别呢?因为在向链表添加元素的时候,需要找到链表待添加位置之前的一个节点,但是对于链表头来说,它没有之前的一个节点. 这时候就需要虚拟的头结点了(dummyHead).这个dummyHead对用户来说是没有意义的,只是方便我们编写逻辑.当有了dummyHead之后我们就不要对头结点进行特殊的处理了. ![](https://box.kancloud.cn/956cd1b7296a606e83b0f3152dd2f64b_1610x437.png) #### 在链表中间添加元素 ![](https://box.kancloud.cn/e91d92b5b9c047a6d79c0e4ff3e4563d_1610x598.png) 在链表中操作的顺序很重要 ![](https://box.kancloud.cn/0e55415873ede5d8b0d3602cf8e99504_1598x613.png) #### 链表元素的删除(需要虚拟头结点) 找到待删除元素之前的那个节点. ![](https://box.kancloud.cn/2502e274e8df16deead1cddf99b85da0_1592x665.png) ### 时间复杂度 链表的增删改查的时间复杂度都是O(n)的,只对链表头操作是O(1) .对于链表来说,适合做的事情,不去修改,查也别查任意位置的元素,只查链表头,增加和删除也只对链表头进行操作.因为链表是动态的,所以不会占用大量的内存空间,具有一定的优势. #### 添加操作 * addLast(e) //O(n) * addFirst(e) //O(1) * add(index e) //O(n/2) = O(n) #### 删除操作 * removeLast(e) //O(n) * removeFirst(e) //O(1) * remove(index e) //O(n/2) = O(n) #### 修改操作 * set(index e) //O(n) #### 查找操作 链表中不用实现find()方法,因为就算拿到了索引,也没办法快速访问. * get(index) //O(n) * contains(e) //O(n)