写在前面:配合leetcode题目效果更好。
一些需要注意的知识点。
- 头结点的值是没有意义的;
- 判断带有头结点链表为空的条件是
head.next==None
- 关于链表的操作都可以概括为:判断操作是否有意义(长度)——找到指定位置——进行操作;
一、插入结点
带有head和不带有head相比,前者在实际应用中要简单很多,后者需要定义head为gobal变量。
将元素插入带有头结点的链表代码如下:
# 在第i个位置插入elem
def Insert(head,i,elem):
assert i>=0
cur=head
while i!=0:
i-=1
cur=cur.next
if not cur:
return False #说明i超过链表长度
temp=cur.next #找到需要插入的位置,cur,temp
cur.next=elem #赋值
ele.next=temp
return True
将元素插入不带有头结点的链表:
def Insert(i,elem):
global head #定义全局变量,否则链表只在函数内部变化
assert i>=0
if i==0: #分为插入位置在头结点和不在头结点两种情况
elem.next=head
head=elem
cur=head
while i>1:
i-=1
cur=cur.next
if not cur:
return False
temp=cur.next
cur.next=elem
elem.next=temp
return True
二、删除元素
# 删除元素
def ListDelete(head,i):
assert i>=0
cur=head
while i!=0:
i-=1
cur=cur.next
if not cur.next:
return False
cur.next=cur.next.next
return False
示例:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。
三、创建单链表
3.1 尾插法创建单链表
基本思想是:先创建一个头结点,依次在head.next插入元素。分为带头结点的单链表和不带头结点的单链表两种情况。
带头结点的单链表:
# 带头结点的单链表:
def BuildLink_Tail(l):
head=ListNode()
temp=head
for elem in l:
temp.next=ListNode(elem) #通过.next遍历所有的值
temp=temp.next
return head
head=BuildLink_Tail([1,2,3,4])
while head.next:
head=head.next
prtin(head.val)
不带头结点的单链表
# 不带头结点的单链表
def BuildLink_Tail(l):
if not l:
return None
head=ListNode(l[0])
temp=head
for elem in i[1:]:
temp.next=ListNode(elem)
temp=temp.next
return head
head=BuildLink_Tail([2,3,4,5])
while head.next:
print(head.val)
head=head.next
3.2 头插法创建单链表
基本思想是:将元素插入到head.next的位置,插入后形成的链表为倒序。
带有头结点:
#带有头结点
def BuildLink_Head(l):
head=ListNode()
for elem in l:
temp=head.next
head.next=ListNode(elem,temp)
#相当于新加的元素和链表head.next形成一个新的链表添加在head后面
return head
不带头结点:
# 不带头结点
def BuildLink_Head(l):
head=None #没有头结点
for elem i l:
head=ListNode(elem,head)
#相当于将元素不断插入到第一个位置(头部)
return head
四、双链表
双链表中的元素不仅可以指向下一个也可以指向上一个。解决单链表无法逆向索引的问题。
class DLinkNode:
def _init_(self,val=0,next=None,prior):
self.val=val
self.next=next
self.prior=prior
五、循环链表
循环单链表:从一个结点出发可以找到其他任何结点。尾部元素.next=head
循环双链表:从头到尾和从尾到头的时间复杂度都是O(1)。