链表理论基础
什么是链表:链表是一种通过指针串联在一起的线性结构,每一个节点由两部分组成,一个是数据域一个是指针域(存放指向下一个节点的指针),最后一个节点的指针域指向null(空指针的意思)。链表的入口节点称为链表的头结点也就是head。
链表的类型:1单链表,单链表中的指针域只能指向节点的下一个节点:
2双链表,每一个节点有两个指针域,一个指向下一个节点,一个指向上一个节点,双链表既可以向前查询也可以向后查询:
3循环链表,就是链表首尾相连,循环链表可以用来解决约瑟夫环问题:
链表的存储方式:数组在内存中是连续分布的,但是链表在内存中不是连续分布的。链表是通过指针域的指针链接在内存中的各个节点,所以链表中的节点在内存中不是连续分布的,而是散乱分布在内存中的某地址上,分配机制取决于操作系统的内存管理。
链表的定义:
# 单链表 singly-linked list
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
删除节点:如图,删除D节点只需要将C节点的next指针指向E节点即可:
添加节点:如图
链表的增添和删除都是O(1)操作,也不会影响到其他节点。但是要注意,要是删除第五个节点,需要从头节点查找到第四个节点通过next指针进行删除操作,查找的时间复杂度是O(n)。
性能分析:链表和数组进行对比:
移除链表元素
力扣203
链表操作中,可以使用原链表来直接进行删除操作,也可以设置一个虚拟头结点再进行删除操作。
移除头结点:原链表方法是将头结点向后移动一位,设置虚拟头结点的方法中移除头结点的操作跟移除其他节点的操作是统一的。
方法一:使用原链表来直接进行删除操作
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def removeElements(self, head: Optional[ListNode], val: int) -> Optional[ListNode]:
while head and head.val == val: #处理头结点
head = head.next
if not head: #链表为空
return head
node = head #上面处理后node指向的头结点值一定不是val
while node.next: #处理下一个节点,如果是None说明node已经指向最后一个节点
if node.next.val == val:
node.next = node.next.next
else:
node = node.next
return head
方法二:设置一个虚拟头结点再进行删除操作
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def removeElements(self, head: Optional[ListNode], val: int) -> Optional[ListNode]:
dummy_head = ListNode(next = head) #设置虚拟头结点
node = dummy_head
while node.next != None: #处理下一个节点,如果是None说明node已经指向最后一个节点
if node.next.val == val:
node.next = node.next.next
else:
node = node.next
return dummy_head.next
方法三:递归。首先对除头结点外其他节点进行删除操作,然后判断头结点值是否等于val,如果等于返回head.next,如果不等于返回head。对上述过程递归,终止条件是head为空,此时直接返回head。
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def removeElements(self, head: Optional[ListNode], val: int) -> Optional[ListNode]:
if head is None:
return head
head.next = self.removeElements(head.next, val) #注意要加self,否则无法调用removeElements函数
return head.next if head.val == val else head
#head.next及之后的链表在深层递归过程中已经做了删除值为val节点的处理,
#因此只需判断当前递归层中head值是否为val即可
学习自【代码随想录】