无序列表抽象数据类型
如上所述,无序列表的结构是项的集合,其中每个项保持相对于其他项的相对位置。下面给出了一些可能的无序列表操作。
- List() 创建一个新的空列表。它不需要参数,并返回一个空列表。
- add(item) 向列表中添加一个新项。它需要 item 作为参数,并不返回任何内容。假定该 item 不在列表中。
- remove(item) 从列表中删除该项。它需要 item 作为参数并修改列表。假设项存在于列表中。
- search(item) 搜索列表中的项目。它需要 item 作为参数,并返回一个布尔值。
- isEmpty() 检查列表是否为空。它不需要参数,并返回布尔值。
- size()返回列表中的项数。它不需要参数,并返回一个整数。
- append(item) 将一个新项添加到列表的末尾,使其成为集合中的最后一项。它需要 item 作为参数,并不返回任何内容。假定该项不在列表中。
- index(item) 返回项在列表中的位置。它需要 item 作为参数并返回索引。假定该项在列表中。
- insert(pos,item) 在位置 pos 处向列表中添加一个新项。它需要 item 作为参数并不返回任何内容。假设该项不在列表中,并且有足够的现有项使其有 pos 的位置。
- pop() 删除并返回列表中的最后一个项。假设该列表至少有一个项。
- pop(pos) 删除并返回位置 pos 处的项。它需要 pos 作为参数并返回项。假定该项在列表中。
实现无序列表:链表
链表实现的基本构造块是节点。每个节点对象必须至少保存两个信息。首先,节点必须包含列表项本身。我们将这个称为节点的数据字段。此外,每个节点必须保存对下一个节点的引用。Node 类还包括访问,修改数据和访问下一个引用的常用方法。
如上所述,无序列表将从一组节点构建,每个节点通过显式引用链接到下一个节点。只要我们知道在哪里找到第一个节点(包含第一个项),之后的每个项可以通过连续跟随下一个链接找到。考虑到这一点,UnorderedList 类必须保持对第一个节点的引用。
'''
Node类:
链表实现的基本构造块是节点。每个节点对象必须至少保存两个信息。
首先,节点必须包含列表项本身。我们将这个称为节点的数据字段。
此外,每个节点必须保存对下一个节点的引用。
'''
class Node:
def __init__(self, initdata):
self.data = initdata
self.next = 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
'''
如上所述,无序列表将从一组节点构建,每个节点通过显式引用链接到下一个节点。
只要我们知道在哪里找到第一个节点(包含第一个项),之后的每个项可以通过连续跟随下一个链接找到。
'''
class UnorderedList:
# 每个链表对象将维护对链表头部的单个引用
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
# 要实现 size 方法,我们需要遍历链表并对节点数计数。
def size(self):
current = self.head
count = 0
while current != None:
count = count + 1
current = current.getNext()
return count
# 在链表中搜索也使用遍历技术
def search(self, item):
current = self.head
found = False
while current != None and not found:
if current.getData() == item:
found = True
else:
current = current.getNext()
return found
# remove 方法需要两个逻辑步骤。首先,我们需要遍历列表寻找我们要删除的项。
# 为了删除包含项的节点,我们需要修改上一个节点中的链接,以便它指向当前之后的节点。
def remove(self, item):
current = self.head
previous = None
found = False
while not found:
if current.getData() == item:
found = True
else:
previous = current
current = current.getNext()
if previous == None:
self.head = current.getNext()
else:
previous.setNext(current.getNext())
if __name__ == '__main__':
mylist = UnorderedList()
mylist.add(31)
mylist.add(77)
mylist.add(17)
mylist.add(93)
mylist.add(26)
mylist.add(54)
print(mylist.search(17))
有序列表抽象数据结构
我们现在将考虑一种称为有序列表的列表类型。例如,如果上面所示的整数列表是有序列表(升序),则它可以写为 17,26,31,54,77和93
。由于 17 是最小项,它占据第一位置。同样,由于 93 是最大的,它占据最后的位置。
有序列表的结构是项的集合,其中每个项保存基于项的一些潜在特性的相对位置。排序通常是升序或降序,并且我们假设列表项具有已经定义的有意义的比较运算。许多有序列表操作与无序列表的操作相同。
- OrderedList() 创建一个新的空列表。它不需要参数,并返回一个空列表。
- add(item) 向列表中添加一个新项。它需要 item 作为参数,并不返回任何内容。假定该 item 不在列表中。
- remove(item) 从列表中删除该项。它需要 item 作为参数并修改列表。假设项存在于列表中。
- search(item) 搜索列表中的项目。它需要 item 作为参数,并返回一个布尔值。
- isEmpty() 检查列表是否为空。它不需要参数,并返回布尔值。
- size()返回列表中的项数。它不需要参数,并返回一个整数。
- index(item) 返回项在列表中的位置。它需要 item 作为参数并返回索引。假定该项在列表中。
- pop() 删除并返回列表中的最后一个项。假设该列表至少有一个项。
- pop(pos) 删除并返回位置 pos 处的项。它需要 pos 作为参数并返回项。假定该项在列表中。
实现有序列表
为了实现有序列表,我们必须记住项的相对位置是基于一些潜在的特性。
为了实现 OrderedList 类,我们将使用与前面看到的无序列表相同的技术。再次,head
的引用为 None
表示为空链表
当我们考虑有序列表的操作时,我们应该注意,isEmpty
和size
方法可以与无序列表一样实现,因为它们只处理链表中的节点数量,而不考虑实际项值。同样,remove
方法将正常工作,因为我们仍然需要找到该项,然后删除它。剩下的两个方法,search
和 add
,将需要一些修改。
'''
Node类:
链表实现的基本构造块是节点。每个节点对象必须至少保存两个信息。
首先,节点必须包含列表项本身。我们将这个称为节点的数据字段。
此外,每个节点必须保存对下一个节点的引用。
'''
class Node:
def __init__(self, initdata):
self.data = initdata
self.next = 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
'''
如上所述,无序列表将从一组节点构建,每个节点通过显式引用链接到下一个节点。
只要我们知道在哪里找到第一个节点(包含第一个项),之后的每个项可以通过连续跟随下一个链接找到。
'''
class orderedList:
# 每个链表对象将维护对链表头部的单个引用
def __init__(self):
self.head = None
def isEmpty(self):
return self.head == None
# 链表结构只为我们提供了一个入口点,即链表的头部。所有其他节点只能通过访问第一个节点,然后跟随下一个链接到达。
# 这意味着添加新节点的最简单的地方就在链表的头部。 换句话说,我们将新项作为链表的第一项,现有项将需要链接到这个新项后。
def add(self, item):
current = self.head
previous = None
stop = False
while current != None and not stop:
if current.getData() > item:
stop = True
else:
previous = current
current = current.getNext()
temp = Node(item)
if previous == None:
temp.setNext(self.head)
self.head = temp
else:
temp.setNext(current)
previous.setNext(temp)
# 要实现 size 方法,我们需要遍历链表并对节点数计数。
def size(self):
current = self.head
count = 0
while current != None:
count = count + 1
current = current.getNext()
return count
# 在链表中搜索也使用遍历技术,由于这是有序列表,一旦节点中的值变得大于我们正在搜索的项,搜索就可以停止并返回 False
def search(self, item):
current = self.head
found = False
stop = False
while current != None and not found and not stop:
if current.getData() == item:
found = True
else:
if current.getData() > item:
stop = True
else:
current = current.getNext()
return found
# remove 方法需要两个逻辑步骤。首先,我们需要遍历列表寻找我们要删除的项。
# 为了删除包含项的节点,我们需要修改上一个节点中的链接,以便它指向当前之后的节点。
def remove(self, item):
current = self.head
previous = None
found = False
while not found:
if current.getData() == item:
found = True
else:
previous = current
current = current.getNext()
if previous == None:
self.head = current.getNext()
else:
previous.setNext(current.getNext())
if __name__ == '__main__':
mylist = orderedList()
mylist.add(31)
mylist.add(77)
mylist.add(17)
mylist.add(93)
mylist.add(26)
mylist.add(54)
print(mylist.search(17))