class Node(object):
"""Represnet a single linked node"""
def __init__(self, data, next=None):
"""Instantiates a Node with a default next of Node"""
self.data = data
self.next = next
if __name__ == "__main__":
lyst = list(range(6,1,-1))
print(lyst)
head = None
for count in range(5):
# print(lyst[count])
head = Node(lyst[count],head)
"""
[6,5,4,3,2]
插入顺序:
[6][\]
[5][->][6][\]
[4][->][5][->][6][\]
[3][->][4][->][5][->][6][\]
[2][->][3][->][4][->][5][->][6][\]
"""
"""
打印时以插入相反顺序打印
2
3
4
5
6
"""
while head != None:
print(head.data)
head = head.next
"""
上个while循环打印显示数据中head会指针重置为下一个节点,直到head指针变为None。因此,在这个过程的最后,
节点实际上都从链表结构中删除。对于程序来说节点不再可用,并且会在下一次垃圾回收时回收。
下面的这个循环打印数据不会打印链表结构,因为head 已经在上次打印数据时重置为零。
"""
while head != None:
print(head.data)
head = head.next
# 遍历操作
"""
使用一个指针临时变量,这个指针变量先初始化为链表结构的head指针,然后控制一个循环,这样在打印链表结构后不会删除节点
链表结构还可以再次访问。
"""
# 重新生成链表
lyst = list(range(6,1,-1))
head = None
for count in range(5):
head = Node(lyst[count], head)
"""
probe 2
probe 3
probe 4
probe 5
probe 6
"""
probe = head
while probe != None:
print("probe", probe.data)
probe = probe.next
"""
probe_t 2
probe_t 3
probe_t 4
probe_t 5
probe_t 6
"""
probe_t = head
while probe_t != None:
print("probe_t", probe_t.data)
probe_t = probe_t.next
class Node(object):
"""Represnet a single linked node"""
def __init__(self, data, next=None):
"""Instantiates a Node with a default next of Node"""
self.data = data
self.next = next
if __name__ == "__main__":
lyst = list(range(6, 1, -1))
head = None
for count in range(5):
head = Node(lyst[count], head)
"""
probe 2
probe 3
probe 4
probe 5
probe 6
"""
# 搜索
# 返回 targetItem has been found! 4
# 访问一个排好序的链表也是一次顺序搜索操作,必须从第一个节点开始访问;并不如数组的随机访问高效
targetItem = 4
probe = head
while probe != None and targetItem != probe.data:
probe = probe.next
if probe != None:
print("targetItem has been found!" ,targetItem)
else:
print("target not in lyst")
# 遍历、搜索、访问某一项的时间复杂度都是线性的,并不需要额外的内存
class Node(object):
"""Represnet a single linked node"""
def __init__(self, data, next=None):
"""Instantiates a Node with a default next of Node"""
self.data = data
self.next = next
if __name__ == "__main__":
lyst = list(range(6, 1, -1))
print(lyst)
head = None
for count in range(5):
head = Node(lyst[count], head)
"""
probe 2
probe 3
probe 4
probe 5
probe 6
"""
"""
[6, 5, 4, 3, 2]
3
4
5
5
"""
i = 3 #访问第4项
probe = head
while i > 0:
probe = probe.next
print(probe.data)
i -= 1
print(probe.data)
class Node(object):
"""Represnet a single linked node"""
def __init__(self, data, next=None):
"""Instantiates a Node with a default next of Node"""
self.data = data
self.next = next
if __name__ == "__main__":
lyst = list(range(6, 1, -1))
print(lyst)
head = None
for count in range(5):
head = Node(lyst[count], head)
"""
probe 2
probe 3
probe 4
probe 5
probe 6
"""
# 替换,时间和空间复杂度都是线性的
targetItem = 4
newItem = 44
probe = head
while probe != None and targetItem != probe.data:
probe = probe.next
if probe != None:
probe.data = newItem
print(probe.data)
else:
print(targetItem, "not in")
# 时间和空间复杂度都是常数
class Node(object):
"""Represnet a single linked node"""
def __init__(self, data, next=None):
"""Instantiates a Node with a default next of Node"""
self.data = data
self.next = next
if __name__ == "__main__":
lyst = list(range(6, 1, -1))
print(lyst)
head = None
for count in range(5):
head = Node(lyst[count], head)
"""
probe 2
probe 3
probe 4
probe 5
probe 6
"""
# 在开始出插入
"""
[6, 5, 4, 3, 2]
1
2
3
4
5
6
"""
newItem = 1
head = Node(newItem, head)
probe = head
while probe != None:
print(probe.data)
probe = probe.next
# 在末尾插入,时间复杂度是线性的,空间复杂度是常数
class Node(object):
"""Represnet a single linked node"""
def __init__(self, data, next=None):
"""Instantiates a Node with a default next of Node"""
self.data = data
self.next = next
if __name__ == "__main__":
lyst = list(range(6, 1, -1))
print(lyst)
head = None
for count in range(5):
head = Node(lyst[count], head)
"""
probe 2
probe 3
probe 4
probe 5
probe 6
"""
# 在末尾插入
"""
newItem = 7
newNode = Node(newItem) #默认next为None
if head is None:
head = newNode
print("head is None")
else:
probe = head
print("head is", head.data, head)
while probe.next != None:
print(probe.data, probe.next)
probe = probe.next
probe.next = newNode
probe = probe.next
print(probe.data, probe.next)
"""
[6, 5, 4, 3, 2]
head is 2 <__main__.Node object at 0x000002DA86DBC400>
2 <__main__.Node object at 0x000002DA86DBC3C8>
3 <__main__.Node object at 0x000002DA86DBC390>
4 <__main__.Node object at 0x000002DA86DBC358>
5 <__main__.Node object at 0x000002DA86DADC88>
7 None
"""
# 删除开始节点,时间和空间复杂度都是常数
class Node(object):
"""Represnet a single linked node"""
def __init__(self, data, next=None):
"""Instantiates a Node with a default next of Node"""
self.data = data
self.next = next
if __name__ == "__main__":
lyst = list(range(6, 1, -1))
print(lyst)
head = None
for count in range(5):
head = Node(lyst[count], head)
"""
probe 2
probe 3
probe 4
probe 5
probe 6
"""
# 从开始处删除
"""
[6, 5, 4, 3, 2]
3
"""
head = head.next
print(head.data)
# 删除最后一个节点,时间和空间复杂度都是线性的
class Node(object):
"""Represnet a single linked node"""
def __init__(self, data, next=None):
"""Instantiates a Node with a default next of Node"""
self.data = data
self.next = next
if __name__ == "__main__":
lyst = list(range(6, 1, -1))
print(lyst)
head = None
for count in range(5):
head = Node(lyst[count], head)
"""
打印返回,这样删不掉最后一个节点
[6, 5, 4, 3, 2]
2
3
4
5
6
"""
removedItem = head.data
if head.next == None:
head = None
else:
probe = head
while probe.next != None:
probe = probe.next
probe = None
probe = head
while probe != None:
print(probe.data)
probe = probe.next
"""
[6, 5, 4, 3, 2]
2
3
4
5
"""
removedItem = head.data
if head.next == None:
head = None
else:
probe = head
while probe.next.next != None: # 必须这样才可以删除最后一个节点
probe = probe.next
probe.next = None
probe = head
while probe != None:
print(probe.data)
probe = probe.next
# 任意位置处插入,时间复杂度线性,空间复杂度常数
class Node(object):
"""Represnet a single linked node"""
def __init__(self, data, next=None):
"""Instantiates a Node with a default next of Node"""
self.data = data
self.next = next
if __name__ == "__main__":
lyst = list(range(6, 1, -1))
print(lyst)
head = None
for count in range(5):
head = Node(lyst[count], head)
index = 4
newItem = 44
if head == None or index <= 0:
head = Node(newItem, head)
else:
probe = head
while probe.next != None and index > 1:
probe = probe.next
# print(probe.data)
index -= 1
print(probe.data) # 5
# probe = Node(newItem, probe)# 这里用probe = Node(newItem, probe)插入失败,不明白为什么?
probe.next = Node(newItem, probe.next) # 必须这样才可以
"""
插入失败
[6, 5, 4, 3, 2]
5
2
3
4
5
6
"""
"""
插入成功
[6, 5, 4, 3, 2]
5
2
3
4
5
44
6
"""
probet = head
while probet != None:
print(probet.data)
probet = probet.next
# 任意位置删除
class Node(object):
"""Represnet a single linked node"""
def __init__(self, data, next=None):
"""Instantiates a Node with a default next of Node"""
self.data = data
self.next = next
if __name__ == "__main__":
lyst = list(range(6, 1, -1))
print(lyst)
head = None
for count in range(5):
head = Node(lyst[count], head)
"""
probe 2
probe 3
probe 4
probe 5
probe 6
"""
# 从任意位置删除
"""
[6, 5, 4, 3, 2]
5
2
3
4
5
"""
index = 4 # 删除下标为4,第5个节点
if index <= 0 or head.next == None: #链表只有一个节点,或者删除第一个节点
head = head.next
else:
probe = head
while index > 1 and probe.next.next != None:
probe = probe.next
index -= 1
print(probe.data)
probe.next = probe.next.next
probe = head
while probe != None:
print(probe.data)
probe = probe.next
在排好序的链表结构上,能否对某一项执行二叉搜索?如果不能,给出理由。
链表结构访问某一节点,需要从开始顺序访问,不像数组可以靠索引随机访问。
Python列表使用数组而不是链表来保存项,请对此给出一个理由。
当数组很大时,访问某个元素,链表的时间O(n)是不能容忍的,而数组的访问操作复杂度是O(1).
class Node(object):
"""Represnet a single linked node"""
def __init__(self, data, next=None):
"""Instantiates a Node with a default next of Node"""
self.data = data
self.next = next
def insertNode(insertItem, index, head):
if index <= 0 or head is None:
head = Node(insertItem, head)
else:
probe = head
while probe.next != None and index > 1:
probe = probe.next
index -= 1
probe.next = Node(insertItem, probe.next)
probe = head
while probe != None:
print(probe.data)
probe = probe.next
if __name__ == "__main__":
lyst = list(range(6, 1, -1))
print(lyst)
head = None
for count in range(5):
head = Node(lyst[count], head)
"""
probe 2
probe 3
probe 4
probe 5
probe 6
"""
# 从任意位置删除
"""
[6, 5, 4, 3, 2]
5
2
3
4
5
"""
insertNode(44, 0, head)
"""
[6, 5, 4, 3, 2]
44
2
3
4
5
6
"""
# 带哑头节点的循环链表没有写出来怎么实现的
单链表结构的时间复杂度
第i个位置访问 | O(n),平均情况 |
第i个位置替换 | O(n),平均情况 |
开始处插入 | O(1) ,最好和最差情况 |
开始处删除 | O(1) ,最好和最差情况 |
第i个位置插入 | O(n),平均情况 |
第i个位置删除 | O(n),平均情况 |
末尾插入 | O(n),平均情况 |
末尾删除 | O(n),平均情况 |
链表的优点
- 插入删除速度快(因为有next指针指向其下一个节点,通过改变指针的指向可以方便的增加删除元素)
- 内存利用率高,不会浪费内存(可以使用内存中细小的不连续空间(大于node节点的大小),并且在需要空间的时候才创建空间)
- 大小没有固定,拓展很灵活。
链表的缺点
- 不能随机查找,必须从第一个开始遍历,查找效率低