双向链表

- Data 数据 + Next 指针 + Prev 指针,组成一个双向链表的内存结构;
- 第一个内存结构称为 链头,最后一个内存结构称为 链尾;
- 链头的 Prev 指针设置为 NULL, 链尾的 Next 指针设置为 NULL;
- Prev 指向的内存结构称为 前驱, Next 指向的内存结构称为 后继;
- 双向链表的遍历是双向的,即如果把从链头的 Next 一直到链尾的[NULL] 遍历方向定义为正向,那么从链尾的 Prev 一直到链头 [NULL ]遍历方向就是反向;
class Node:
def __init__(self, datap, prev=None, nextval=None):
self.datap = datap
self.prev = prev
self.nextval = nextval
def __repr__(self):
return "{}<={}=>{}".format(
self.prev.datap if self.prev else None,
self.datap,
self.nextval.datap if self.nextval else None)
class DoubleLinkedList:
def __init__(self, datap=None):
if datap:
self.head = Node(datap)
self.tail = self.head
self.len = 1
else:
self.head = None
self.tail = None
self.len = 0
def append(self, value):
node = Node(value)
if not self.head:
self.head = node
self.tail = node
self.len += 1
else:
self.tail.nextval = node
node.prev = self.tail
self.tail = node
self.len += 1
def appendleft(self, value):
node = Node(value)
if not self.head:
self.head = node
self.tail = node
self.len += 1
else:
self.head.prev = node
node.nextval = self.head
self.head = node
self.len += 1
def __iter__(self):
curser = self.head
while curser:
yield curser
if curser == self.tail:
break
curser = curser.nextval
def __len__(self):
return self.len
def index(self, value):
current = self.head
for i, node in enumerate(self):
if node.datap == value:
return i
break
else:
raise ValueError("{} not in DoubleLinkedList".format(value))
def __getitem__(self, index):
if index >= self.len or index < -self.len:
raise IndexError("DoubleLinkedList index out of range")
for i, node in enumerate(self):
if i == index or i == self.len + index:
return node
def __setitem__(self, index, value):
self[index].datap = value
def insert(self, index, value):
if index <= 0:
self.appendleft(value)
elif index >= self.len:
self.append(value)
else:
nextnode = self[index]
prevnode = self[index].prev
node = Node(value)
node.nextval = nextnode
node.prev = prevnode
prevnode.nextval = node
nextnode.prev = node
self.len += 1
def remove(self, value):
if self.head is None:
raise ValueError("{} not in DoubleLinkedList".format(value))
else:
for i, node in enumerate(self):
if node.datap == value:
if self.len == 1:
self.head = None
self.tail = None
self.len -= 1
break
else:
if node == self.head:
self.head = node.nextval
self.head.prev = None
self.len -= 1
break
elif node == self.tail:
self.tail = node.prev
self.tail.nextval = None
self.len -= 1
break
else:
prevnode = node.prev
nextnode = node.nextval
prevnode.nextval = nextnode
nextnode.prev = prevnode
self.len -=1
break
else:
raise ValueError()
def delet(self, index):
if self.head is None:
raise ValueError("{} not in DoubleLinkedList".format(value))
if index >= self.len or index < -self.len:
raise IndexError("DoubleLinkedList index out of range")
for i, node in enumerate(self):
if i == index or i == self.len + index:
current = node
prevnode = current.prev
nextnode = current.nextval
if self.len == 1:
self.head = None
self.tail = None
self.len -= 1
elif prevnode is None:
self.head = nextnode
nextnode.prev = None
self.len -= 1
elif nextnode is None:
self.tail = prevnode
prevnode.nextval = None
self.len -= 1
else:
prevnode.nextval = nextnode
nextnode.prev = prevnode
self.len -= 1
def pop(self):
if self.head is None:
raise IndexError(": pop from empty DoubleLinkedList")
elif self.len == 1:
self.head = None
self.tail = None
self.len -= 1
else:
self.tail = self.tail.prev
self.tail.nextval = None
self.len -= 1
def popleft(self):
if self.head is None:
raise IndexError(": pop from empty DoubleLinkedList")
elif self.len == 1:
self.head = None
self.tail = None
self.len -= 1
else:
self.head = self.head.nextval
self.head.prev = None
self.len -= 1
def __repr__(self):
return "{}".format([i for i in self])
def con:
if x in self:
l1 = DoubleLinkedList(1)
l1.append(2)
for i in reversed(l1):
print(i.datap)
for i in l1:
print(i.datap)