课时27双向链表及添加元素。
单向链表里,所有区域都指向后项节点,只能从头开始往后找。
而把节点扩充一下,就可以使数据区前面的一个区域保存上一个节点的地址。
后继节点:当前节点的下一个。
前驱节点:当前节点的上一个。
长度,遍历,是否为空与单链表一样。
而添加元素,在头部插入的情况下,要使插入的节点的next区域,指向原本的第一个节点。
接着使head指向新的节点。
接着使原本的节点的prev区域指向要插入的节点。
而也可以先使原本的节点的prev指向插入节点后,再使head指向新节点。
在链表的尾部添加元素,则需要游标从头找到尾部。
使游标所指的节点的next区域指向插入节点,而插入结点的prev区域指向游标所在的节点即可。
而如果该链表是空链表的话,直接使head等于插入节点即可。
而指定位置插入节点,之前用了两个游标,而双链表不需要。 直接使插入节点的prev指向cur的上一个节点,而插入节点的next区域指向cur的节点即可。
注意先后顺序。如果先让cur.prev=node的话,那么通过cur,已经不能找到“40”这个节点了。
因此,此时要通过node来找到前面“40”的节点。
课时28
查找时与单链表相同。
删除时,使cur的的前一个节点的next区域指向cur的next区域指向的区域。
使cur的节点的下一个节点的prev区域,指向cur的prev区域的前一个区域。
class Node(object):
"""节点"""
def __init__(self,item):
self.elem=None
self.next=None
self.prev=None
class DoubleLinkList(object):
#双链表
def __init__(self,node=None):
self.__head=node
def is_empty(self):
return self.__head==None
def length(self):
"""链表长度"""
"""cur游标,用来移动遍历节点"""
cur = self.__head
"""count记录数量"""
count = 0
while cur != None:
count += 1
cur = cur.next
return count
def travel(self):
"""遍历整个链表"""
cur = self.__head
while cur != None:
print(cur.elem, end=" ") # 一进入循环,就打印游标当前的东西.
cur = cur.next
print("")
def add(self, item):
"""链表头部添加元素"""
node = Node(item) # 将item封装为一个节点
node.next = self.__head # 让新节点的next区域,指向head指向的部分
self.__head = node # 让头直接指向新的节点。
node.next.prev=node #使原本的节点的prev区域指向新节点。
def append(self,item):
"""尾部插入节点"""
"""应该让游标一直走,走到尾部,才能进行添加"""
"""但是实际使用时,应该让用户不用关心游标,直接传入一个节点,便能在该节点出添加"""
node=Node(item)
if self.is_empty():
self.__head=node
else:
cur=self.__head
while cur.next!=None:
cur=cur.next
cur.next=node
node.prev=cur
def insert(self, pos, item): # pos为指定的位置
"""指定位置添加元素"""
""":param pos 从0开始"""
if pos <= 0:
self.add(item) # pos小于或等于零,那么就是在头部插入元素,即用头插法。
elif pos > self.length() - 1:
self.append(item) # 如果pos大于链表最后的下标,那么就是在尾部添加。
else:
cur = self.__head
count = 0
while count < pos:
count += 1
cur = cur.next
# 推出时,使cur的位置就是pos的位置
node = Node(item)
node.next = cur
node.prev = cur.prev
cur.prev = node
def search(self, item):
"""查找元素"""
cur = self.__head # 如果是空链表,则此步就会让cur为None,直接跳过循环返回False。
while cur.next != Node:
if cur.elem == item:
return True
else:
cur = cur.next
return False # 整个循环结束都没有找到元素,则返回False
def remove(self,item):
"""删除节点"""
cur=self.__head
while cur.next!=None:
if cur.elem==item:#判断当前数据是否是用户想要删除的
#先判斷此节点是否是头节点
if cur==self.__head:
self.__head=cur.next
if cur.next:#如果cur.next存在
#判断链表是否只有一个节点。
cur.next.prev=None
else:
cur.prev.next=cur.next
if cur.next:
cur.next.prev=cur.prev
break
else:
cur=cur.next