(以下参考来源代码随想录训练营资料)
链表的定义:链表是一种通过指针串联在一起的线性结构,每一个节点由两部分组成,一个是数据域一个是指针域(存放指向下一个节点的指针),最后一个节点的指针域指向null。
如图单链表:
![](https://img-blog.csdnimg.cn/img_convert/dc389fad607516445773516bf2a67b10.png)
双链表:每一个节点有两个指针域,一个指向下一个节点,一个指向上一个节点。
双链表 既可以向前查询也可以向后查询。
如图双链表:
![](https://img-blog.csdnimg.cn/img_convert/b4bc51900dc5880057072cb538a9d08e.png)
如图循环链表:
![](https://img-blog.csdnimg.cn/img_convert/009eab18fc897eacedc914e9032b9cc6.png)
链表的存储方式:数组是在内存中是连续分布的,但是链表在内存中不是连续分布的。而是散乱分布在内存中的某地址上,分配机制取决于操作系统的内存管理。
如图所示:
![](https://img-blog.csdnimg.cn/img_convert/c73b1d254925578f1dde148185ffec64.png)
链表的操作:
删除节点:
![](https://img-blog.csdnimg.cn/img_convert/135804ff2658fdc994f5ac6d4f3ca2d2.png)
只要将C节点的next指针 指向E节点就可以了。在C++里最好是再手动释放这个D节点,释放这块内存。其他语言例如Java、Python,就有自己的内存回收机制,就不用自己手动释放了。
添加节点:
![](https://img-blog.csdnimg.cn/img_convert/a6ad686b38f0733f4e7e13b467daabb3.png)
可以看出链表的增添和删除都是O(1)操作,也不会影响到其他节点。但是要注意,要是删除第五个节点,需要从头节点查找到第四个节点通过next指针进行删除操作,查找的时间复杂度是O(n)。
链表与数组性能分析:
![](https://img-blog.csdnimg.cn/img_convert/aa2e800bf2a30b06ce9050d827311c8c.png)
定义链表:(c/c++)
// 单链表
struct ListNode {
int val; // 节点上存储的元素
ListNode *next; // 指向下一个节点的指针
ListNode(int x) : val(x), next(NULL) {} // 节点的构造函数
};
python:
class ListNode:
def __init__(self, val, next=None):
self.val = val
self.next = next