DSA - 链表
Last updated
Last updated
各种数据结构的底层实现都是数组和链表,数组和链表的根本区别在于它们使用内存的方式。
如果将计算机内存简单看成下图那样,每一个内存单元就是一个小格子。
可以看到,数组是需要连续空间的,而链表则不一定。
由于数组是连续的内存空间,因此:
可以按下标随机访问,访问的时间复杂度是 $O(1)$。
插入或者删除操作很麻烦,由于需要移动插入/删除元素后面的所有元素,时间复杂度平均是 $O(N)$。只有在数组尾部进行插入/删除操作时间复杂度才是 $O(1)$。
总的来说,数组是【查询友好,插入/删除不友好】。
而链表不要求连续的内存空间,各个节点可以随意散落在内存中,节点之间通过 next
指针连起来就行,所以:
需要通过遍历来查找某一个节点,访问的时间复杂度是 $O(N)$。
插入或者删除操作很方便,插入操作只需要在内存中随便找一个空格子存节点数据,然后把原链表尾部节点的 next
指针指向这个格子就好了。删除则只需要把待删除节点的空间回收,并把指向它的指针改为指向下一个节点就行。
插入,给定节点插入位置的话,时间复杂度是 $O(1)$,否则还要遍历找到插入的节点位置,时间为 $O(N)$。
删除,$O(1)$,如果要先找到删除节点,时间也是 $O(N)$。
遍历,$O(N)$。
都是线性的数据结构,只在细微的操作和使用场景上有差别。
指针的修改
链表的拼接
典型的题目是 反转链表
。
反转链表模板
反转任意一段链表:
JavaScript Code
比如反转链表 II,以及合并有序链表等。
环
边界
递归
虚拟头
快慢指针