使用链表构建列表类。
链表:由一系列节点(链表中每个元素称为节点)组成。每个节点包括两部分:一个是存储数据元素的数据域(Data field),另一个是存储下一个节点地址的指针域(Pointer field)。
下面这些方法的实现性能与Python的内置列表list不同,Python中的列表的实现是基于数组的。
打印显示类:
class Display(object):
def show(self):
return ", ".join("{}".format(getattr(self, key)) for key in self.__dict__)
# 重写__str__定义对象的打印内容
def __str__(self):
return "{}".format(self.show())
创建节点类:需继承Display类,否则print时只会显示内存地址
class Node(Display):
def __init__(self, initdata):
self.data = initdata #初始化数据元素
self.next = None #下一个节点地址,None意味着没有下一个节点。
# 获取数据元素
def getData(self):
return self.data
# 获取下一个节点地址
def getNext(self):
return self.next
# 设置数据元素
def setData(self, newdata):
self.data = newdata
# 设置下一个节点地址
def setNext(self, newnext):
self.next = newnext
无序列表类:需继承Display类,否则print时只会显示内存地址
class UnorderedList(Display):
def __init__(self):
self.head = None #初始化列表头
# 列表是否为空
def isEmpty(self):
return self.head == None
# 添加元素
def add(self, item):
temp = Node(item) #创建节点
temp.setNext(self.head) #将当前节点的指针指向原列表头
self.head = temp #重置列表头为将当前节点
# 元素数量
def size(self):
current = self.head #外部引用,列表头赋值给当前
count = 0 #初始计数为0
while current != None: #当当前未到列表尾部,则继续循环
count += 1 #计数加1
current = current.getNext() #获取下一个节点作为当前
return count
# 搜索元素
def search(self, item):
current = self.head #外部引用,列表头赋值给当前
while current != None: #当当前未到列表尾部,则继续循环
if current.getData() == item: #如果当前数据与要查找的数据相同,则
return True #找到了
else:
current = current.getNext() #获取下一个节点作为当前
return False #到列表尾部了,说明没找到
# 移除
def remove(self, item):
current = self.head #外部引用,列表头赋值给当前
previous = None #外部引用,None赋值给上一步previous
found = False
while not found:
if current.getData() == item: #找到了
found = True
else: #没找到
previous = current #前进一步,将当前赋值给上一步previous
current = current.getNext() #前进一步,获取下一个节点作为当前
if previous == None: #如果previous没变化,说明要移除的是列表第一个元素
self.head = current.getNext() #则将下一个节点作为列表头
else:
previous.setNext(current.getNext()) #将previous的指针设置为下一个节点
# 剩下的方法:插入(insert),索引(index),弹出(pop)等等。任何一个操作中都要同时考虑对象在列表头部和其他位置这两种情况。同样,插入、索引、弹出需要我们给列表中的位置命名。我们假定列表中位置的名称是从0开始的整数。
li = UnorderedList()
li.add(54)
li.add(26)
li.add(93)
li.add(17)
li.add(77)
li.add(31)
print(li) #需__str__重构,否则打印显示的是内存地址
print(li.search(54))
print(li.isEmpty())
print(li.size())
print(li.remove(31))
print(li.remove(54))
print(li)
print(li.search(31))
print(li.isEmpty())
print(li.size())
结果为:
31, 77, 17, 93, 26, 54, None
True
False
6
None
None
77, 17, 93, 26, None
False
False
4
有序列表类:(此处为升序列表,在search中有影响),需继承Display类,否则print时只会显示内存地址
class OrderedList(Display):
def __init__(self):
self.head = None #初始化列表头
# 列表是否为空
def isEmpty(self):
return self.head == None
# 添加元素
def add(self, item):
current = self.head #外部引用,列表头赋值给当前
previous = None #外部引用,None赋值给上一步previous
while current != None: #当当前未到列表尾部,则继续循环
if current.getData() > item: #若当前值>要添加的值,则
break #跳出循环
else:
previous = current #前进一步,将当前赋值给上一步previous
current = current.getNext() #前进一步,获取下一个节点作为当前
temp = Node(item) #创建节点
if previous == None: #如果previous没变化,说明要添加的是列表第一个元素
temp.setNext(self.head) #将当前节点的指针指向原列表头
self.head = temp #重置列表头为将当前节点
else:
temp.setNext(current) #将新增节点的指针指向下一个节点
previous.setNext(temp) #将上一个节点的指针指向新增节点
# 元素数量
def size(self):
current = self.head #外部引用,列表头赋值给当前
count = 0 #初始计数为0
while current != None: #当当前未到列表尾部,则继续循环
count += 1 #计数加1
current = current.getNext() #获取下一个节点作为当前
return count
# 搜索元素
def search(self, item):
current = self.head #外部引用,列表头赋值给当前
while current != None: #当当前未到列表尾部,则继续循环
if current.getData() == item: #如果当前数据与要查找的数据相同,则
return True #找到了
else:
if current.getData() > item: #在升序列表中的元素值>要查找的值,则
return False #后面也没有要找的了,不必继续循环查找
else:
current = current.getNext() #获取下一个节点作为当前
return False #到列表尾部了,说明没找到
# 移除
def remove(self, item):
current = self.head #外部引用,列表头赋值给当前
previous = None #外部引用,None赋值给上一步previous
found = False
while not found:
if current.getData() == item: #找到了
found = True
else: #没找到
previous = current #前进一步,将当前赋值给上一步previous
current = current.getNext() #前进一步,获取下一个节点作为当前
if previous == None: #如果previous没变化,说明要移除的是列表第一个元素
self.head = current.getNext() #则将下一个节点作为列表头
else:
previous.setNext(current.getNext()) #将previous的指针设置为下一个节点
lii = OrderedList()
lii.add(26)
lii.add(17)
lii.add(54)
lii.add(31)
lii.add(93)
lii.add(77)
print(lii) #需__str__重构,否则打印显示的是内存地址
print(lii.search(54))
print(lii.isEmpty())
print(lii.size())
print(lii.remove(31))
print(lii.remove(54))
print(lii)
print(lii.search(31))
print(lii.isEmpty())
print(lii.size())
结果为:
17, 26, 31, 54, 77, 93, None
True
False
6
None
None
17, 26, 77, 93, None
False
False
4