1.链表基础定义
之前已经把两大数据结构之一的数组总结了,这次就来总结另一个——链表(Linked List)。首先动态数组、栈和队列的底层都是依托于静态数组的;靠resize来解决固定容量问题,这可能会造成内存空间的大量浪费(比如当数组满了后,会自动加倍容量,但如果没有继续添加元素,其实是有多一倍的容量浪费了);插入和删除时需要移动大量元素。而链表则是真正的动态数据结构。
一句话总结:数据存储在‘节点’(Node)中。

如果一个节点的next是空的,则它就是最后一个节点了。因此,链表的优点是实现真正的动态,不需要处理固定容量的问题;而缺点是丧失了随机访问的能力(因为链表节点在计算机底层内存的位置不是连续的)。
所以,再跟数组来对比如下:

2.链表增删改查
2.1基本功能
链表的第一个元素我们定义为head。

class LinkedList:
class _Node:
def __init__(self, e=None):
self.e = e
self.next = None
def __str__(self):
return str(self.e)
def __repr__(self):
return self.__str__()
def __init__(self):
self.__head = None
self._size = 0
def get_size(self):
return self._size
def is_empty(self):
return self._size == 0
2.2链表添加元素
之前数组我们是在尾部添加元素是方便的(因为数组的size变量是指向数组中最后一个元素的下一个位置,即下一个添加元素的位置),而链表是在头部添加元素更加方便。
比如现在我们想把内容为666的一个节点添加到链表的头部,且不破坏链表原有结构。

先把666的节点的next指向现在的链表head。

然后把head指向666的节点。

头部添加的实现如下(跟栈类似):
def add_first(self, e):
node = self._Node(e)
node.next = self.__head
self.__head = node
self._size += 1
而尾部添加的实现跟队列比较类似:
def add_last(self, e):
node = self._Node(e)
if self.__head is None:
self.__head = node
self._size += 1
return
cur = self.__head
pre = None
while cur:
pre = cur
cur = cur.next
# 当cur 为最后一个节点时带入,pre更新为最后一个节点,cur更新为最后一个节点的下一个节点即为空,
# 下一次while cur 时会退出循环,此时的pre表示的就是最后一个节点,将node挂到pre的后面即可
pre.next = node
self._size += 1
# 查找链表中有没有item,有返回True,没有则返回False
现在我们想在链表任意位置添加元素,比如在‘索引’(链表其实没有索引这个概念)为2的地方添加元素666,即我们需要在1和2中间插入一个666。

首先我们需要搜索一下666之前的节点是谁,显然我们插入666后索引是2,则之前的节点就从0开始遍历到索引为1的位置(prev找到1)。

然后就把666插入(注意顺序!)。


所以关键是要找到待插入节点的前一个位置(prev指向的位置)。然而,如果我们如果要插入头部的位置的话,head是没有前面的位置的,这时我们需要做一个特殊的处理。具体实现如下:
def add(self, index, e):
if index < 0 or index > self._size:
raise ValueError('Add failed. Illegal index.')
if index == 0:
#特殊情况:插到链表头部,
self.add_first(e)
return
prev = self.__head
for i in range(index-1):
prev = prev.next
node = self._Node(e)
node.next = prev.next
prev.next = node
self._size += 1
然后前面的add_first和add_last都可以调用add了:
def add_first(self, e):
self.add(0, e)
def add_last(self, e):
self.add(self._size, e)
另外我们思考插入666的时候能不能把两个步骤的顺序换一下呢?首先,如果先把prev指向666,这时候2是没有指向它了,那自然是找不到它的位置了。


然后我们建一个打印链表的函数,方便查看插入的程序对不对。
def __str__(self):
curr = self.__head
data = []
while curr:
data.append(str(curr.e))
curr = curr.next
return '(Head) ' + \
' -> '.join(data) + ' (Tail)'
def __repr__(self):
return self.__str__()
检验一下!
if __name__ == '__main__':
linkedlist = LinkedList()
print(linkedlist.get_size())
linkedlist.add_first(1)
linkedlist.add_first(2)
linkedlist.add_first(4)
linkedlist.add_first(5)
print(linkedlist)
linkedlist.add(1,6)
print(linkedlist)
0
(Head) 5 -> 4 -> 2 -> 1 (Tail)
(Head) 5 -> 6 -> 4 -> 2 -> 1 (Tail)
我们再来深究一下为什么在链表头部添加元素会比较特殊呢?因为head是没有前面的节点的,所以逻辑上会特殊一点。但是我们可以在head前面设立一个虚拟头节点(不存储任何元素),即链表真正的头节点(dummyHead),但这个虚拟头节点是对用户屏蔽的。这时就不需要对头节点进行特殊处理了。


有了这个虚拟头节点后,我们可以改写一下之前的功能:
class LinkedList:
class _Node:
def __init__(self, e=None):
self.e = e
self.next = None
def __str__(self):
return str(self.e)
def __repr__(self):
return self.__str__()
'''
原来的初始化
def __init__(self):
self.__head = None
self._size = 0
'''
def __init__(self):
self._dummy_head = self._Node()#dummyhead的节点没有内容
self._size = 0
def get_size(self):
return self._size
def is_empty(self):
return self._size == 0
def add_first(self, e):
self.add(0, e)
def add_last(self, e):
self.add(self._size, e)
def add(self, index, e):
if index < 0 or index > self._size:
raise ValueError('Add failed. Illegal index.')
'''
if index == 0:
self.add_first(e)
return
prev = self.__head
'''
prev = self._dummy_head
for i in range(index-1):
prev = prev.next
node = self._Node(e)
node.next = prev.next
prev.next = node
self._size += 1
def __str__(self):
'''
curr = self.__head
'''
curr = self._dummy_head.next
data = []
while curr:
data.append(str(curr.e))
curr = curr.next
return '<chapter_04_LinkedList.linkedlist.LinkedList>: (Head) ' + \
' -> '.join(data) + ' (Tail)'
def __repr__(self):
return self.__str__()
2.3链表遍历、查询、更新
def get(self, index):
if index < 0 or index >= self._size:
raise ValueError('Get failed. Illegal index.')
curr = self._dummy_head.next
for i in range(index):
curr = curr.next
return curr.e
def get_first(self):
return self.get(0)
def get_last(self):
return self.get(self._size - 1)
def setter(self, index, e):
if index < 0 or index >= self._size:
raise ValueError('Set failed. Illegal index.')
curr = self._dummy_head.next
for i in range(index):
curr = curr.next
curr.e = e
def contains(self, e):
curr = self._dummy_head.next
while curr:
if curr.e == e:
return True
curr = curr.next
return False
def __str__(self):
curr = self._dummy_head.next
data = []
while curr:
data.append(str(curr.e))
curr = curr.next
return '<chapter_04_LinkedList.linkedlist.LinkedList>: (Head) ' + \
' -> '.join(data) + ' (Tail)'
def __repr__(self):
return self.__str__()
检验:
if __name__ == '__main__':
linkedlist = LinkedList()
print(linkedlist.get_size())
linkedlist.add_first(1)
linkedlist.add_first(2)
linkedlist.add_first(4)
linkedlist.add_first(5)
print(linkedlist.get_size())
print(linkedlist)
print(linkedlist.get(3))
print(linkedlist.get_first())
print(linkedlist.get_last())
linkedlist.setter(3,6)
print(linkedlist)
0
4
<chapter_04_LinkedList.linkedlist.LinkedList>: (Head) 5 -> 4 -> 2 -> 1 (Tail)
1
5
1
<chapter_04_LinkedList.linkedlist.LinkedList>: (Head) 5 -> 4 -> 2 -> 6 (Tail
2.4链表删除元素
比如我们要删除索引为2位置的元素(记住链表是没有索引的概念,只是为了方便这里讲解)。

首先我们要找到2之前的那个节点,即prev的指向的位置。


把2跳过,现在的2顺序上是找不到它的位置了。

另外为了python尽可能回收空间,我们手动让2的节点为空,即delNode.next = null。此时真正意义上把2从链表里删除了。

def remove(self, index):
if index < 0 or index >= self._size:
raise ValueError('Remove failed. Illegal index.')
prev = self._dummy_head
for i in range(index):
prev = prev.next
ret = prev.next
prev.next = ret.next
ret.next = None
self._size -= 1
return ret.e
def remove_first(self):
return self.remove(0)
def remove_last(self):
return self.remove(self._size - 1)
def __str__(self):
curr = self._dummy_head.next
data = []
while curr:
data.append(str(curr.e))
curr = curr.next
return '<chapter_04_LinkedList.linkedlist.LinkedList>: (Head) ' + \
' -> '.join(data) + ' (Tail)'
def __repr__(self):
return self.__str__()
检验:
if __name__ == '__main__':
linkedlist = LinkedList()
print(linkedlist.get_size())
linkedlist.add_first(1)
linkedlist.add_first(2)
linkedlist.add_first(4)
linkedlist.add_first(5)
print(linkedlist)
linkedlist.remove(2)
linkedlist.remove_first()
linkedlist.remove_last()
print(linkedlist)
0
<chapter_04_LinkedList.linkedlist.LinkedList>: (Head) 5 -> 4 -> 2 -> 1 (Tail)
<chapter_04_LinkedList.linkedlist.LinkedList>: (Head) 4 (Tail)
3.静态链表
这个内容是把一个数据结构转化成另一个数据结构,但难度较大,在面试中也不常见,属于拓展思路的内容。
链表及下面涉及的新链表形式都是依赖于指针实现的,但早期的编程语言没有指针,有人想出用数组来代替指针从而表示单链表。
首先我们让数组的元素都由两个数据域来组成(val表示数据内容和cur相当于链表中next指针)。另外,我们对数组第一个和最后一个元素都做了特殊处理,不存数据(都是有意去浪费这两个空间)。

来看一个例子,现在我们已经把一组数据(甲乙丙…庚)存放到静态链表里,能看到甲存有下一个元素乙的游标值(即2),以此类推,直到庚是最后一个有值的元素,我们就把庚的cur设置为0。最后一个元素存的是第一个有值元素的下标(即1),第一个元素存的是备用列表的第一个位置下标(即7).

现在我们打算把丙插入乙和丁之间,第一步我们把丙扔到空闲空间第一位(即7),第二步告诉乙把它的cur改成7,第三步把丙的cur改成3,搞定!其实跟单链表插入的原理差不多。

#静态链表
class Node:
def __init__(self, cur, val=None):
# 值
self.val = val
# 游标。最后一个元素的游标必须是0
self.cur = cur
class linkList:
# 分配线性表长度、定义线性表
def __init__(self):
self.MAX_SIZE = 7 #一般会设为1000这样大的空间,防止插入后溢出,这里是为了方便之后打印检查
self.node = list()
for i in range(self.MAX_SIZE):
if i == self.MAX_SIZE-1:
self.node.append(Node(0))
else:
self.node.append(Node(i+1))
# 指定位置插入元素
def add(self, i, e):
k = self.MAX_SIZE-1
if i < 1 or i > self.ListLength()+1:
return 0
j = self.findEmpty()
if (j):
self.node[j].val = e
for l in range(1,i):
k = self.node[k].cur
self.node[j].cur = self.node[k].cur
self.node[k].cur = j
return 1
return 0
# 查找空位置
def findEmpty(self):
i = self.node[0].cur
if (self.node[0].cur):
self.node[0].cur = self.node[i].cur
return i
def ListLength(self):
j = 0
i = self.node[self.MAX_SIZE-1].cur
while(i):
i = self.node[i].cur
j = j+1
return j
# 删除线性表指定位置的元素
def remove(self, i):
if i < 1 or i > self.ListLength():
return 0
k = self.MAX_SIZE-1
for j in range(1,i):
k = self.node[k].cur
j = self.node[k].cur
self.node[k].cur = self.node[j].cur
self.delempty(j)
def delempty(self, k):
self.node[k].cur = self.node[0].cur
self.node[0].cur = k
# 按照索引遍历
def travel(self):
for i in range(0, self.MAX_SIZE):
print("i==", i, "; val==", self.node[i].val, "; cur==", self.node[i].cur)
ll = linkList()
ll.travel()
print("start")
ll.add(1, 'B')
ll.travel()
print("start")
ll.add(2, 'Bc')
ll.travel()
print("start")
ll.add(3, 'Bcd')
ll.travel()
print("del")
ll.remove(1)
ll.travel()
i== 0 ; val== None ; cur== 1
i== 1 ; val== None ; cur== 2
i== 2 ; val== None ; cur== 3
i== 3 ; val== None ; cur== 4
i== 4 ; val== None ; cur== 5
i== 5 ; val== None ; cur== 6
i== 6 ; val== None ; cur== 0
start
i== 0 ; val== None ; cur== 2
i== 1 ; val== B ; cur== 0
i== 2 ; val== None ; cur== 3
i== 3 ; val== None ; cur== 4
i== 4 ; val== None ; cur== 5
i== 5 ; val== None ; cur== 6
i== 6 ; val== None ; cur== 1
start
i== 0 ; val== None ; cur== 3
i== 1 ; val== B ; cur== 2
i== 2 ; val== Bc ; cur== 0
i== 3 ; val== None ; cur== 4
i== 4 ; val== None ; cur== 5
i== 5 ; val== None ; cur== 6
i== 6 ; val== None ; cur== 1
start
i== 0 ; val== None ; cur== 4
i== 1 ; val== B ; cur== 2
i== 2 ; val== Bc ; cur== 3
i== 3 ; val== Bcd ; cur== 0
i== 4 ; val== None ; cur== 5
i== 5 ; val== None ; cur== 6
i== 6 ; val== None ; cur== 1
del
i== 0 ; val== None ; cur== 1
i== 1 ; val== B ; cur== 4
i== 2 ; val== Bc ; cur== 3
i== 3 ; val== Bcd ; cur== 0
i== 4 ; val== None ; cur== 5
i== 5 ; val== None ; cur== 6
i== 6 ; val== None ; cur== 2
总的来说,静态链表的优点是插入和删除元素时,我们只需要更改游标,而不需要直接移动元素;缺点是它依然是一个静态结构,而且失去顺序存储结构能随机存储的一个特性(现在的index和cur不是一一对应的)。本质上,静态链表只是为了那些没有指针的高级语言所设计的方法。
4.双向链表
引例:
当一辆高铁起点站是上海,终点站是北京,现在我们想从北京去上海,but链表不能反向遍历。

所以我们在一个节点里面加了个指向前端节点的prev,这样一个节点既可以指向前方,也可以指向后方,这种能提升链表综合性能的新形式是双向链表。
#双向链表
class Node(object):
def __init__(self, elem):
"""双链表结点"""
self.elem = elem
self.pre = None
self.next = None
class DoubleLinkedList(object):
def __init__(self, node=None):
self.__head = node
def is_empty(self):
"""判断链表是否为空"""
return self.__head is None
def length(self):
"""获取链表长度"""
cur = self.__head
count = 0
while cur is not None:
count += 1
cur = cur.next
return count
def travel(self):
"""遍历链表"""
cur = self.__head
while cur is not None:
print(cur.elem, end=' ')
cur = cur.next
print()
def addFirst(self, elem):
"""向双链表头部添加元素"""
node = Node(elem)
if self.is_empty(): # 链表为空
self.__head = node
else:
node.next = self.__head
node.next.pre = node
self.__head = node
def addLast(self, elem):
"""向链表尾部添加结点"""
node = Node(elem)
if self.is_empty():
self.__head = node
else:
cur = self.__head
while cur.next is not None:
cur = cur.next
cur.next = node
node.pre = cur
def add(self, pos, elem):
"""向链表位置pos处插入元素elem"""
if pos == 0:
self.addFirst(elem)
elif pos > self.length() or pos < 0:
raise ValueError('Add failed. Illegal index.')
else:
node = Node(elem)
cur = self.__head
pre = None
for i in range(pos):
pre = cur
cur = cur.next
pre.next = node
node.pre = pre
node.next = cur
if cur:
cur.pre = node
def remove(self, elem):
"""删除链表中第一个值为elem的结点"""
if self.is_empty():
return
cur = self.__head
while cur is not None:
if cur.elem == elem:
if cur == self.__head: # 若是头结点
self.__head = cur.next # 链表中只有一个结点
if cur.next:
cur.next.pre = None
else:
cur.pre.next = cur.next
if cur.next: # 如果不是尾结点
cur.next.pre = cur.pre
break
else:
cur = cur.next
def search(self, elem):
"""查找链表中是否存在元素elem"""
cur = self.__head
while cur is not None:
if cur.elem == elem:
return True
else:
cur = cur.next
return False
if __name__ == '__main__':
double_linked_list = DoubleLinkedList()
print(double_linked_list.is_empty())
print('===================')
double_linked_list.addLast(1)
print('===================')
double_linked_list.addLast(2)
double_linked_list.addLast(3)
double_linked_list.addFirst(7)
double_linked_list.addLast(4)
double_linked_list.addLast(5)
double_linked_list.add(0, 13) # 13, 7, 1, 2, 3, 4, 5
double_linked_list.travel()
double_linked_list.add(2, 99) # 13, 7, 99, 1, 2, 3, 4, 5
double_linked_list.travel()
double_linked_list.add(8, 22) # 13, 7, 99, 1, 2, 3, 4, 5, 22
double_linked_list.travel()
double_linked_list.remove(13)
double_linked_list.travel() # 7 99 1 2 3 4 5 22
double_linked_list.remove(22)
double_linked_list.travel() # 7 99 1 2 3 4 5
double_linked_list.remove(3)
double_linked_list.travel() # 7 99 1 2 4 5
print(double_linked_list.search(100)) # False
print(double_linked_list.search(7)) # True
print(double_linked_list.search(2)) # True
print(double_linked_list.search(5)) # True
True
===================
===================
13 7 1 2 3 4 5
13 7 99 1 2 3 4 5
13 7 99 1 2 3 4 5 22
7 99 1 2 3 4 5 22
7 99 1 2 3 4 5
7 99 1 2 4 5
False
True
True
True
5.单向循环链表
引例:
当一辆高铁起点站是上海,终点站是北京,现在我们想从南京直接去北京,but链表要求我们必须从头开始遍历,实在不方便。

单链表终端的节点的next一般指向null,现在把它指向头节点,使得整个链表成为一个环,这种头尾相连的链表就称为单向循环链表。

这种新链表形式解决了一个问题:我们可以从当中的一个节点出发,然后可以访问链表全部节点。
#单向循环链表
class Node(object):
def __init__(self, elem):
"""单循环链表结点"""
self.elem = elem
self.next = None
class SinglyLinkedCircularList(object):
"""单向循环链表"""
def __init__(self, node=None):
self.__head = node
def is_empty(self):
"""判断链表是否为空"""
return self.__head is None
def length(self):
"""求链表长度"""
if self.is_empty():
return 0
cur = self.__head
count = 1 # 下方循环退出时,链表至少有一个结点
while cur.next != self.__head:
count += 1
cur = cur.next
return count
def travel(self):
"""遍历链表"""
if self.is_empty():
return
cur = self.__head
while cur.next != self.__head:
print(cur.elem, end=' ')
cur = cur.next
# 退出循环时,cur指向最后一个结点
print(cur.elem)
def addFirst(self, elem):
"""向链表头部添加元素"""
node = Node(elem)
if self.is_empty():
node.next = node
self.__head = node
else:
node.next = self.__head
cur = self.__head
while cur.next != self.__head:
cur = cur.next
cur.next = node
self.__head = node
def addLast(self, elem):
"""向链表尾部添加元素"""
node = Node(elem)
if self.is_empty():
node.next = node
self.__head = node
else:
cur = self.__head
while cur.next != self.__head:
cur = cur.next
node.next = self.__head
cur.next = node
def add(self, pos, elem):
"""向链表位置pos处插入元素
Args:
pos: 插入的位置,从0开始计数
elem: 插入的元素
"""
if pos <= 0:
self.addFirst(elem)
elif pos > (self.length() - 1):
self.addLast(elem)
else:
pre = self.__head
count = 0
while count < (pos - 1):
count += 1
pre = pre.next
# 退出循环,pre指向插入位置的前一个结点
node = Node(elem)
node.next = pre.next
pre.next = node
def remove(self, elem):
"""删除链表中第一个为elem的元素"""
if self.is_empty():
return
cur = self.__head
pre = None
if cur.elem == elem:
if cur.next != self.__head:
while cur.next != self.__head:
cur = cur.next
cur.next = self.__head.next
self.__head = self.__head.next
else:
self.__head = None
else:
pre = self.__head
while cur.next != self.__head:
if cur.elem == elem:
pre.next = cur.next
return
else:
pre = cur
cur = cur.next
if cur.elem == elem:
pre.next = cur.next
def search(self, elem):
"""查找链表中是否存在元素elem"""
if self.is_empty():
return False
cur = self.__head
while cur.next != self.__head:
if cur.elem == elem:
return True
else:
cur = cur.next
# 退出循环,cur指向尾结点
if cur.elem == elem:
return True
return False
if __name__ == '__main__':
singly_linked_circular_list = SinglyLinkedCircularList()
print(singly_linked_circular_list.is_empty())
print(singly_linked_circular_list.length())
print('===================')
singly_linked_circular_list.addLast(1) #1
print(singly_linked_circular_list.is_empty())
print(singly_linked_circular_list.length())
print('===================')
singly_linked_circular_list.addLast(2)#1,2
singly_linked_circular_list.addLast(3)#1,2,3
singly_linked_circular_list.addFirst(7)
singly_linked_circular_list.addLast(4)
singly_linked_circular_list.addLast(5) # 7, 1, 2, 3, 4, 5
singly_linked_circular_list.add(0, 13) # 13, 7, 1, 2, 3, 4, 5
singly_linked_circular_list.travel()
singly_linked_circular_list.add(2, 99) # 13, 7, 99, 1, 2, 3, 4, 5
singly_linked_circular_list.travel()
singly_linked_circular_list.add(11, 22) # 13, 7, 99, 1, 2, 3, 4, 5, 22
singly_linked_circular_list.travel()
singly_linked_circular_list.remove(13)
singly_linked_circular_list.travel() # 7 99 1 2 3 4 5 22
singly_linked_circular_list.remove(22)
singly_linked_circular_list.travel() # 7 99 1 2 3 4 5
singly_linked_circular_list.remove(3)
singly_linked_circular_list.travel() # 7 99 1 2 4 5
print(singly_linked_circular_list.search(666)) # False
print(singly_linked_circular_list.search(7)) # True
print(singly_linked_circular_list.search(5)) # True
print(singly_linked_circular_list.search(1)) # True
True
0
===================
False
1
===================
13 7 1 2 3 4 5
13 7 99 1 2 3 4 5
13 7 99 1 2 3 4 5 22
7 99 1 2 3 4 5 22
7 99 1 2 3 4 5
7 99 1 2 4 5
False
True
True
True
6.双向循环链表
#双向循环链表
class Node(object):
def __init__(self, elem):
"""双链表结点"""
self.elem = elem # 该节点值
self.next = None # 连接一下一个节点
self.prev = None # 上一个节点值
class DoubleCircleLinkedList(object):
def __init__(self, node=None):
self._head = node
def is_empty(self):
"""判断链表是否为空"""
return self._head is None
def length(self):
"""获取链表长度"""
if self.is_empty():
return 0
else:
cur = self._head.next
n = 1
while cur != self._head:
cur = cur.next
n += 1
return n
def travel(self):
"""遍历链表"""
cur = self._head
while cur.next != self._head:
print(cur.elem, end=' ')
cur = cur.next
print(cur.elem)
def addFirst(self, elem):
"""向双链表头部添加元素"""
node = Node(elem)
if self.is_empty(): # 链表为空
node.next = node
node.prev = node
self._head = node
else:
node.next = self._head
node.prev = self._head.prev
self._head.prev.next = node
self._head.prev = node
self._head = node
def addLast(self, elem):
"""向链表尾部添加结点"""
if self.is_empty():
self.addFirst(elem)
else:
node = Node(elem)
cur = self._head.next
while cur.next != self._head:
cur = cur.next
cur.next = node
node.prev = cur
node.next = self._head
self._head.prev = node
def add(self, pos, elem):
"""向链表位置pos处插入元素elem"""
if pos <= 0:
self.addFirst(elem)
elif pos >= self.length():
self.addLast(elem)
else:
cur = self._head.next
n = 1
while cur.next != self._head:
if n == pos:
break
cur = cur.next
n += 1
node = Node(elem)
node.prev = cur.prev
cur.prev.next = node
node.next = cur
cur.prev = node
def remove(self, elem):
"""删除链表中第一个值为elem的结点"""
if self.is_empty():
return
else:
if self._head.elem == elem:
if self.length == 1:
self._head = Node
else:
self._head.prev.next = self._head.next
self._head.next.prev = self._head.prev
self._head = self._head.next
cur = self._head.next
while cur != self._head:
if cur.elem == elem:
cur.prev.next = cur.next
cur.next.prev = cur.prev
cur = cur.next
def search(self, elem):
"""查找链表中是否存在元素elem"""
if self.is_empty():
return False
else:
cur = self._head.next
if self._head.elem == elem:
return True
else:
while cur != self._head:
if cur.elem == elem:
return True
else:
cur = cur.next
return False
if __name__ == '__main__':
double_linked_list = DoubleCircleLinkedList()
double_linked_list.addLast(1)
double_linked_list.addLast(2)
double_linked_list.addLast(3)
double_linked_list.addFirst(7)
double_linked_list.addLast(4)
double_linked_list.addLast(5)
double_linked_list.add(0, 13) # 13, 7, 1, 2, 3, 4, 5
double_linked_list.travel()
double_linked_list.add(2, 99) # 13, 7, 99, 1, 2, 3, 4, 5
double_linked_list.travel()
double_linked_list.add(11, 22) # 13, 7, 99, 1, 2, 3, 4, 5, 22
double_linked_list.travel()
double_linked_list.remove(13)
double_linked_list.travel() # 7 99 1 2 3 4 5 22
double_linked_list.remove(22)
double_linked_list.travel() # 7 99 1 2 3 4 5
double_linked_list.remove(3)
double_linked_list.travel() # 7 99 1 2 4 5
print(double_linked_list.search(100)) # False
print(double_linked_list.search(7)) # True
print(double_linked_list.search(2)) # True
print(double_linked_list.search(5)) # True
13 7 1 2 3 4 5
13 7 99 1 2 3 4 5
13 7 99 1 2 3 4 5 22
7 99 1 2 3 4 5 22
7 99 1 2 3 4 5
7 99 1 2 4 5
False
True
True
True

23万+

被折叠的 条评论
为什么被折叠?



