Python数据结构之有序列表
一.基本介绍
在有序列表中,元素的相对位置取决于它们的基本特征。它们通常以升序或者降序排列,并且我们假设元素之间能进行有意义的比较。有序列表和无序列表(链表)的许多操作都是相同的。
二.代码实现
class OrderedList:
"""有序列表类"""
def __init__(self):
"""初始化有序列表的头部,使其为None"""
self.head = None
def is_empty(self):
"""判断有序列表的头部是否为空"""
return self.head == None
def size(self):
"""返回有序列表中节点的数量"""
current = self.head
count = 0
while current != None:
count += 1
current = current.next_node
return count
def remove(self,data):
"""删除有序列表中的指定节点"""
current = self.head
previous = None
while current != None:
if current.data == data:
if previous == None:
self.head = current.next_node
else:
previous.next_node = current.next_node
return
previous = current
current = current.next_node
print(f"{data} is not in the list")
def add(self,data):
"""向有序列表中添加节点"""
temp = Node(data)
current = self.head
previous = None
if current == None:
temp.next_node = self.head
self.head = temp
while current != None:
if current.data > data:
temp.next_node = current
previous.next_node = temp
break
previous = current
current = current.next_node
def search(self,data):
"""查找指定的元素是否在有序列表中"""
current = self.head
while current != None:
if current.data == data:
return True
elif current.data > data:
return False
current = current.next_node
return False
但是,上面这段代码有很多地方是需要优化的
- 推荐使用is或者is not,而不是==或!=
这是因为is用于比较两个对象的身份(即它们是否是同一个对象)。在Python中,None是一个特殊的单例对象,这意味着在整个程序的生命周期中,None只有一个实例。使用is检查None是检查变量是否指向唯一的那个None对象
2.==操作符用于判断两个对象的值是否相等,对于自定义对象,==操作符的行为可以通过定义__eq__方法来改变
3.使用is None表明你正在检查变量是否为None,而不是检查变量的值是否等于None,语义更明确,代码更易读和易于维护
4.is操作符直接比较对象的身份,是一个非常快速的操作,==操作符可能会通过__eq__方法重写使得本身不是None的对象在==None时返回True
5.在add方法中temp.next_node = self.head是没有多余的,因为此时有序列表是空列表,头部没有元素,self.head本身就是None,直接设置self.head=temp就足够了
优化后的代码
class OrderedList:
"""有序列表类"""
def __init__(self):
"""构造函数,初始化有序列表的表头"""
self.head = None
def is_empty(self):
"""检查有序列表是否为空"""
return self.head is None
def add(self,data):
"""向有序列表中添加节点"""
temp = Node(data)
current = self.head
previous = None
if current is None: # 如果有序列表头部为空
self.head = temp
while current is not None: # 如果头部且当前节点都不为空
if current.data > data: # 如果当前节点的数据大于要插入的数据,说明要插入的数据应该放在当前节点的前面
if previous is None: # 如果目标节点比有序列表头部节点小,此时previous为None
self.head = temp
else: # 目标节点比有序列表头部节点大,previous一定不为None
previous.next_node = temp
temp.next_node = current
return
previous = current
current = current.next_node
def search(self,data):
"""检查指定的节点是否在有序列表中"""
current = self.head
while current is not None:
if current.data == data:
return True
current = current.next_node
return False
def remove(self,data):
"""从有序列表中删除指定的节点"""
current = self.head
previous = None
while current is not None:
if current.data == data:
if previous == None:
self.head = current.next_node
else:
previous.next_node = current.next_node
return
previous = current
current = current.next_node
raise ValueError(f"{data} is not in the list")
def size(self):
"""返回有序列表中的节点个数"""
current = self.head
count = 0
while current is not None:
count += 1
current = current.next_node
return count
def display(self):
"""显示有序列表的结构"""
current = self.head
while current is not None:
print(current.data,end=' -> ')
current = current.next_node
print(None)
依旧有问题,add方法中没有处理要添加的元素是有序列表中的最后一个元素的这种情况
add方法中逻辑混乱
应先判断要添加的位置,在执行添加操作
class OrderdeList:
def __init__(self):
self.head = None
def is_empty(self):
return self.head is None
def add(self,data):
temp = Node(data)
current = self.head
previous = None
while current is not None and current.data < data:
previous = current
current = current.next_node
if previous is None:
temp.next_node = self.head
self.head = temp
else:
previous.next_node = temp
temp.next_node = current
def search(self,data):
current = self.head
while current is not None:
if current.data == data:
return True
current = current.next_node
return False
def remove(self,data):
current = self.head
previous = None
while current is not None:
if current.data == data:
if previous is None:
self.head = current.next_node
else:
previous.next_node = current.next_node
return
previous = current
current = current.next_node
raise ValueError(f"{data} is not in the list")
def size(self):
current = self.head
count = 0
while current is not None:
count += 1
current = current.next_node
return count
def display(self):
current = self.head
while current is not None:
print(current.data,end=' -> ')
current = current.next_node
print(None)