介绍
List
我们首先谈谈列表 List:
- 当我们知道列表的头指针p时,p指向列表第一个元素的地址
- 当我们需要知道列表的第2个元素时,我们只需把头指针+1,即p+1指向第2个元素
- 同理,p+i-1指向数组中第i个元素
也就是说,列表中元素的指针储存在一块连续的内存上,我们要知道下一个元素的指针时,只需将当前元素的指针后移一个单位即可。
链表
但链表不同,其中的元素本身就是一个指针:
- 当我们知道链表的头指针p时,可以通过
p.val取出第一个元素 p.next直接储存了下一个元素的指针- 当我们遍历链表时,只需
p=p.next即可
代码示例
通过代码来说明,能更清楚地感受,LeetCode上最经典的链表结构如下:
class ListNode(object):def __init__(self, x):self.val = xself.next = None
那我们首先创建一个链表:
# 创建 ListNode 格式的链表original_list=[1,2,3,4,5]head=ListNode(None)# 用p_head储存头指针p_head=headfor i in original_list:head.next=ListNode(i)head=head.nexthead=p_head.next
链表的遍历也很简单:
p=headwhile p:print(p.val)p=p.next
如果我们要删除链表中的元素,可以这样:
def deleteNode(head, node):# 储存头指针p_head = headwhile head:if head.val == node:head.val=head.next.valhead.next = head.next.nextreturn p_headelse:head = head.nextreturn p_head
最终代码汇总:
class ListNode(object):def __init__(self, x):self.val = xself.next = Nonedef deleteNode(head, node):# 储存头指针p_head = headwhile head:if head.val == node:head.val=head.next.valhead.next = head.next.nextreturn p_headelse:head = head.nextreturn p_headoriginal_list=[1,2,3,4,5]target=3# 创建 ListNode 格式的链表head=ListNode(None)p_head=headfor i in original_list:head.next=ListNode(i)head=head.nexthead=p_head.nextres=deleteNode(head,target)while res:print(res.val)res=res.next
模板
综合以上,写了一个单向链表的模板
class ListNode:def __init__(self, x):self.val = xself.next = Noneclass SingleList:def __init__(self, L) -> None:self.head = ListNode(None)self.len = len(L)p = self.headfor i in L:p.next = ListNode(i)p = p.nextself.head = self.head.nextdef GetiNode(self, i):n = self.lenif i < 0 or i > n:raise IndexError("Index {} > Length {}".format(i, n))head = self.headfor _ in range(i):head = head.nextreturn headdef Traversal(self, p=None):if not p:p = self.headprint("#"*10+" Traversal Start "+"#"*10)while p:print(p.val)p = p.nextdef DeleteNode(self, node):head = self.headwhile head:if head.val == node:head.val = head.next.valhead.next = head.next.nextreturnelse:head = head.nextif __name__ == "__main__":original_list = [0, 1, 2, 3, 4, 5]SList = SingleList(original_list)SList.Traversal()node = SList.GetiNode(3)SList.Traversal(node)SList.DeleteNode(4)SList.Traversal()
输出结果为:
########## Traversal Start ##########
0
1
2
3
4
5
########## Traversal Start ##########
3
4
5
########## Traversal Start ##########
0
1
2
3
5
为了简化起见,省略了很多边界情况的讨论,更完备的代码请参看
707. 设计链表
