文章目录
Datawhale十月组队学习,LeetCode算法
一、链表的基础知识
1.1链表的构建
Python的链表的构建与C语言不同,与Java类似。Python中构建一个类,在类中创建构造方法定义链表的链节点,其中val存储数据,next存储下一个链节点的地址。
链表结构的优缺点:
- 优点:存储空间不必事先分配,在需要存储空间的时候可以临时申请,不会造成空间的浪费;一些操作的时间效率远比数组高(插入、移动、删除元素等)。
- 缺点:不仅数据元素本身的数据信息要占用存储空间,指针也需要占用存储空间,链表结构比数组结构的空间开销大。
1.2链表的种类
1.单链表:链表最基础的形式,只有一个指针next指向下一个链节点的地址
2.双链表:它的每个链节点中有两个指针,分别指向直接后继和直接前驱。
3.循环链表:它的最后一个链节点指向头节点,形成一个环。
二、链表的基础操作
1.链表的定义
链表的定义是在类中的构造方法中定义的。定义方法有两种即链节点类(即 ListNode 类)和链表类(即 LinkedList 类)。在创建空链表时,只需要把相应的链表头节点变量设置为空链接即可。在 Python 里可以将其设置为 None,其他语言也有类似的惯用值,比如 NULL、nil、0 等。
1.1链节点类(即 ListNode 类)
在构造方法构建,有两部分存储数据的val和存储下一个链节点地址的next
代码如下:
# 链节点类
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
1.2 链表类(即 LinkedList 类)
使用一个链节点变量 $head$ 来表示链表的头节点。
代码如下:
# 链表类
class LinkedList:
def __init__(self):
self.head = None
2.查找元素
从头节点 head开始,沿着链表节点逐一进行查找。如果查找成功,返回被查找节点的地址;否则返回 None。
代码如下:
# 查找元素
def find(self, val):
cur = self.head
while cur:
if val == cur.val:
return cur
cur = cur.next
return None
利用循环,沿着head头节点查找,利用next指针寻找下一个节点的地址。
3. 插入元素
链表中插入元素操作分为三种:
- 链表头部插入元素:在链表第 1 个链节点之前插入值为 val 的链节点。
- 链表尾部插入元素:在链表最后 1 个链节点之后插入值为 val 的链节点。
- 链表中间插入元素:在链表第 i 个链节点之前插入值为 val 的链节点。
3.1链表头部插入元素
* 先创建一个值为 val 的链节点 node。
* 然后将 node 的 next 指针指向链表的头节点 head。
* 再将链表的头节点 head 指向 node。
# 链表头部插入元素
def insertFront(self, val):
node = ListNode(val)
node.next = self.head
self.head = node
3.2链表尾部插入元素
* 先创建一个值为 val 的链节点 node。
* 使用指针 cur 指向链表的头节点 head。
* 通过链节点的 next 指针移动 cur 指针,从而遍历链表,直到 cur.next 为 None。
* 令 cur.next 指向将新的链节点 node。
# 链表尾部删除元素
def removeRear(self):
if not self.head.next:
return 'Error'
cur = self.head
while cur.next.next:
cur = cur.next
cur.next = None
3.3链表中间插入元素
* 使用指针变量 cur 和一个计数器 count。令 cur 指向链表的头节点,count 初始值赋值为 0。
* 沿着链节点的 next 指针遍历链表,指针变量 cur 每指向一个链节点,计数器就做一次计数。
* 当遍历到第 index - 1 个链节点时停止遍历。
* 创建一个值为 val 的链节点 node。
* 将 node.next 指向 cur.next。
* 然后令 cur.next 指向 node。
# 链表中间插入元素
def insertInside(self, index, val):
count = 0
cur = self.head
while cur and count < index - 1:
count += 1
cur = cur.next
if not cur:
return 'Error'
node = ListNode(val)
node.next = cur.next
cur.next = node
4删除元素
- 链表头部删除元素:删除链表的第 1 个链节点。
- 链表尾部删除元素:删除链表末尾最后 1 个链节点。
- 链表中间删除元素:删除链表第 i 个链节点。
4.1链表头部删除元素
直接将 self.head 沿着 next 指针向右移动一步即可。
# 链表头部删除元素
def removeFront(self):
if self.head:
self.head = self.head.next
4.2链表尾部删除元素
* 先使用指针变量 cur 沿着 next 指针移动到倒数第 2 个链节点。
* 然后将此节点的 next 指针指向 None 即可。
# 链表尾部删除元素
def removeRear(self):
if not self.head.next:
return 'Error'
cur = self.head
while cur.next.next:
cur = cur.next
cur.next = None
4.3链表中间删除元素
* 先使用指针变量 cur 移动到第 i - 1 个位置的链节点。
* 然后将 cur 的 next 指针,指向要第 i 个元素的下一个节点即可
# 链表中间删除元素
def removeInside(self, index):
count = 0
cur = self.head
while cur.next and count < index - 1:
count += 1
cur = cur.next
if not cur:
return 'Error'
del_node = cur.next
cur.next = del_node.next