双向链表
定义
每个节点有两个链接:一个指向前一个节点,当此节点为第一个节点时,指向空值;而另一个指向下一个节点,当此节点为最后一个节点时,指向空值。
实现
- 定义节点
class Node(object):
"""双向链表节点"""
def __init__(self, item):
self.item = item
self.next = None
self.prev = None
- 定义双向链表
class DLinkList(SingleLinklist): #可以继承单链表的某些操作
"""双向链表,前四个操作和单链表一样"""
def __init__(self,node=None):
self.__head = None
def is_empty(self):
"""判断链表是否为空"""
return self._head is None
def length(self):
"""返回链表的长度"""
cur = self._head
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=" ") #end=" ",表示不换行
cur=cur.next
- 双链表头部加入元素
def add(self,item): #头部添加数据
node = Node(item) #元素创建节点
node.next = self.__head
self.__head = node
Node.next.prev = node #后节点的前驱指向node
或:
def add(self,item): #头部添加数据
node = Node(item) #元素创建节点
self.__head.prev = node
node.next = self.__head
self.__head = node
- 双链表尾部添加元素
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): #指定位置添加数据
if pos <= 0:
self.add(item)
elif pos > self.length()-1:
self.append(item)
else:
cur = self.__head
count = 0
while count < pos:
count+=1
cur = cur.next
node=Node(item) # 当循环退出后,pre指向pos-1位置
Node.next = cur
node.prev = cur.prev
cur.prev.next = node
cur.prev = node
- 查找
def search(self,item): #查找节点是否存在
cur = self.__head #空链直接返回False
while cur != None:
if cur.elem == item:
return True
else:
cur=cur.next
return False
- 双链表删除节点
def remove(self,item): #删除节点
cur = self_head
while cur != None:
if cur.elem == item: #判断此节点是否是头节点
if cur == self.__head:
self.__head = cur.next
if 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
单向循环链表
- 与单向链表的唯一区别:链表尾部指向第一个元素
class SinglecircleLinkList(object): #创建单链表的类
def __init__(self,node=None): #默认参数是None,实参看传入的数
self.__head = node #设置初始的表头,_head是仅供内部使用,表头指向创建好的节点
if node:
node.next= node #需初始需要将自己的next挂载到自己
- empty不需要改
def is_empty(self): #创造“判断是否为空”的对象操作
return self._head == None # 表头指向空,输出判断结果
def length(self): #创造“列表长度”的对象操作
if self.is_empty():
return 0
Cur = self.__head
count = 1 # count=0导致少数一个
while cur.next != self.__head:
count += 1
cur = cur.next #指针指向节点的next部分,也就是下一个节点的elem部分
return count
额外考虑链表为0,满足while循环,所以不用额外处理
# 创造“遍历整个列表”的对象操作和长度操作相似
def travel(self):
if self.is_empty():
return 0
Cur = self._head
while Cur.next != self.__head:
print(cur.elem,end=" ") #end=" ",表示不换行
cur=cur.next
print(cur) #退出循环时,cur指向尾结点,但节点元素未打印
- 单向循环链表尾部插入元素
def append(self,item): #尾部添加数据
node = Node(item) #元素创建节点
if self.is_empty():
self._head = node #如果为空,表头指向新元素的节点
node.next = node
else:
cur = self._head
while cur.next != None: #指针指向最后一个节点
cur= cur.next
cur.next = node
node.next = self.__head
- 单向循环链表头部插入元素
def add(self,item): #头部添加数据
node = Node(item) #元素创建节点
if self.is_empty():
self.__head = node
node.next = node
else:
cur = self.__head
while cur.next != self.__head:
cur = cur.next
node.next = self.__head
self.__head = node
cur.next = node
- 中间插入和单链表一样
def insert(self,pos,item): #指定位置添加数据
if pos <= 0:
self.add(item)
elif pos > self.length()-1
self.append(item)
else:
pre=self.__head #pre游标指向第一个元素
count = 0
while count < (pos-1):
count+=1
pre = pre.next
node=Node(item) # 当循环退出后,pre指向pos-1位置
node.next = pre.next
pre.next = node
- 删除元素
def remove(self,item): #删除节点
if self.is_empty():
return
cur = self__head
pre = none
while cur.next != self.__head:
if cur.elem == item: #判断此节点是否是头节点
if cur == self.__head: #头节点
rear = self.__head
while rear.next != self.__head:
rear = rear.next
self.__head = cur.next
rear.next = self.__head
else: #中间节点
pre.next = cur.next
return
else:
pre=cur
cur=cur.next
#退出循环,cur指向尾结点
if cur.elem == item:
if cur == self.__head:
self.__head=None
else:
pre.next = cur.next
- 遍历+对比 = 查找
def search(self,item): #查找节点是否存在
cur = self.__head #空链直接返回False
while cur != self__head:
if cur.elem == item:
return True
else:
cur=cur.next
#退出循环,cur指向尾结点
if cur.elem == item: # 检查尾结点
return True
return False