第二章 链表
一、链表理论基础
1、链表的结构
链表是由指针串联在一起的线性结构。
每一个节点由两部分组成,一个是数据域,一个是指针域(存放指向下一个结点的指针),最后一个节点的指针域指向null(空指针)。
链表的入口节点成为链表的头节点,head
2、链表的类型
-
单链表
如上
单链表的指针域只能指向节点的下一个节点 -
双链表
每一个节点有两个指针域,一个指向下一个节点,一个指向上一个节点。
既可以向前查询,也可以向后查询
-
循环链表
链表首尾相连
循环链可以用来解决约瑟夫环问题
3、链表的存储方式
一句话总结:离散,分配机制取决于操作系统的内存管理
链表是通过指针域的指针链接在内存中各个节点。
所以链表中的节点在内存中不是连续分布的 ,而是散乱分布在内存中的某地址上,分配机制取决于操作系统的内存管理。
数据结构 | 内存 | 优势 |
---|---|---|
数组 | 存储数据在内存中的地址是连续的 | 由于是连续的内存空间,所以支持随机访问,通过下标随机访问的时间复杂度是O(1) |
链表 | 离散分布 | 灵活分配空间; |
链表的定义:
class ListNode:
def __init__(self, val, next=None):
self.val = val
self.next = next
二、性能分析
三、链表知识点
1、是否要添加虚拟头结点 :
虚拟头结点的主要目的是为了避免对头结点的特殊处理;这个处理就指的是修改操作。所以可以这样:涉及到对链表修改(如插入,删除,移动)的,都加个dummy,只是遍历取点就可以不用加
2、关于两两交换链表中的节点
while (prev.next != nu11 && prev.next.next != nu11)
这边为什么是&& 不是|| 一个是对于偶数个结点的判断 一个是奇数个结点 那不应该是||的关系吗?
奇数节点就不需要交换了,所以只有满足后面有偶数个节点的时候才会进入循环
3、链表多画图
边界的情况也是,多画
4、链表相交
- 在遇到无法定位头节点,头节点可能被移动删除导致定位失效的时候可以考虑用虚拟头节点,并不是每道题都要用的!!!!
- 不要把值和节点的概念混淆起来 节点是一个实例 占用一块空间 值只是它的成员变量 值怎样和节点本身没有任何关系 一个实例只由它的地址唯一确定!