一、定义
1.1 链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。
1.2 分类:单链表、双向链表、循环链表
1.3 单链表为例组成:结点,结点包含数据和后继指针。结点分为记录基地址的头结点,普通的中间结点,以及为null的尾结点。
二、特点
2.1 插入、删除数据效率高O(1)级别(只需更改指针指向即可),随机访问效率低O(n)级别(需要从链头至链尾进行遍历)。
2.2 和数组相比,内存空间消耗更大,因为每个存储数据的节点都需要额外的空间存储后继指针
三、基本操作
3.1 单链表
3.1.1 查找:由于链表不是连续存储的,所以无法计算得到对应数据,需要遍历得到,时间复杂度O(n)
3.1.2 插入:我们只考虑相邻链表结点的操作,所以时间复杂度为O(1)
3.1.3 删除: 我们只考虑相邻链表结点的操作,所以时间复杂度为O(1)
3.1.3.1 删除结点中值等于给定值的结点
3.1.3.2 删除给定指针指向的结点。
3.1.4 单链表翻转
//单链表翻转 private Node<T> reversed(Node<T> head) { Node pre = null; //一个pre指向当前结点前一个结点 Node current = head; //定义一个当前结点 while (current != null) { Node temp = current.next; current.next = pre; //当前结点指向前序结点 pre = current; //前序结点指向当前结点 current = temp; //后移当前结点 } return pre; }
3.2 双向链表
常用应用:LinkedList和LinkedHashMap
3.3 循环链表
3.3.1 定义:循环链表其实是一种特殊的单链表,唯一区别就是尾结点指向头结点,可以方便的从尾结点找到头结点
3.3.2 经典应用:约瑟夫环问题
四、链表学习技巧
4.1 基础的链表自己实现几遍以及画图配合理解:单链表、循环链表、双向循环链表
4.2 链表基本操作需要熟练掌握:
单链表反转
链表中环的检测
两个有序的链表合并
删除链表倒数第 n 个结点
求链表的中间结点
4.3 关键点技巧注意和理解
4.3.1 指针:指针指向某一个变量,该指针存的是该变量对应的内存地址。理解了指针基本上对于链表的操作就会能够理解了。
例如:p->next=q指的是p 结点中的 next 指针存储了 q 结点的内存地址。
4.3.2 边界条件处理,例如:遍历的时候注意哪个条件会最先到达临界条件。
写完链表代码之后可以常规验证以下条件:
1)空链表
2)一个结点链表
3)两个结点链表
4)头结点和尾结点处理是否正确
4.3.3 多画图辅助理解
4.4 单链表删除操作技巧,一般需要知道要删除结点的前一个结点,所以创建一个哨兵结点指向头结点然后再操作:例如删除链表倒数第n个结点中的慢指针。