1、栈(后进先出,LIFO)
一个栈 (有时称“叠加栈”)是一个项的有序集合。添加项和移除项都发生在同一“端”。
这一端通常被称为“顶”。另一端的顶部被称为“底”。
栈的抽象数据类型
栈的抽象数据类型是由以下结构和操作定义的。堆栈是结构化的,如上面所描述的,栈是一个有序的项的集,项添加和删除的一端称为“顶”。栈的命令是按后进先出进行的。栈的操作如下:
Stack()创建一个新的空栈。它不需要参数,并返回一个空栈。
Push(item)将新项添加到堆栈的顶部。它需要参数 item 并且没有返回值。
pop()从栈顶删除项目。它不需要参数,返回 item。栈被修改。
peek()返回栈顶的项,不删除它。它不需要参数。堆栈不被修改。
isEmpty()测试看栈是否为空。它不需要参数,返回一个布尔值。
size()返回栈的项目数。它不需要参数,返回一个整数。
2、队列(先进先出,FIFO)
队列(Queue)是一系列有顺序的元素的集合,新元素的加入在队列的一端,这一端叫做“队尾”(rear),已有元素的移除发生在队列的另一端,叫做“队首”(front)。当一个元素被加入到队列之后,它就从队尾开始向队首前进,直到它成为下一个即将被移出队列的元素。
队列的抽象数据类型
抽象数据类型队列通过以下的一些结构和操作来定义。如前文所述,一个队列由一系列有序的元素构成,它们从叫做“队尾”的一端进入队列,再从叫做“队首”的另一端被移出队列。队列保持“先进先出”的特性。下面是队列的一些操作:
Queue()创建一个空队列对象,无需参数,返回空的队列;
enqueue(item)将数据项添加到队尾,无返回值;
dequeue()从队首移除数据项,无需参数,返回值为队首数据项;
isEmpty()测试是否为空队列,无需参数,返回值为布尔值;
size()返回队列中的数据项的个数,无需参数。
实现Queue
class Queue:
def __init__(self):
self.items = []
def isEmpty(self):
return self.items == []
def enqueue(self,item):
self.items.insert(0,item)
def dequeue(self):
return self.items.pop()
def size(self):
return len(self.items)
q = Queue()
q.enqueue(4)
q.enqueue('dog')
q.enqueue(True)
print(q.size())
print(q.isEmpty())
q.enqueue(8.4)
print(q.dequeue())
print(q.size())
3、双端队列
双端队列(deque 或 double-ended queue)与队列类似,也是一系列元素的有序组合。其两端称为队首(front)和队尾(rear),元素在到达两端之前始终位于双端队列中。与队列不同的是,双端队列对元素添加和删除的限制不那么严格,元素可以从两端插入,也可以从两端删除。可以说,双端队列这种混合的线性数据结构拥有栈和队列各自拥有的所有功能。
双端队列的抽象数据类型
Deque 抽象数据类型双端队列(Deque)由以下一些结构和操作来定义。如前文所述,双端队列由一系列有序的元素组织而成,元素可以从队首或队尾插入、删除。下面是双端队列的一些操作。
· Deque() 创建一个空双端队列,无参数,返回值为 Deque 对象。
· addFront(item) 在队首插入一个元素,参数为待插入元素,无返回值。
· addRear(item) 在队尾插入一个元素,参数为待插入元素,无返回值
· removeFront() 在队首移除一个元素,无参数,返回值为该元素。双端队列会被改变。
· removeRear() 在队尾移除一个元素,无参数,返回值为该元素。双端队列会被改变。
· isEmpty() 判断双端队列是否为空,无参数,返回布尔值。
· size() 返回双端队列中数据项的个数,无参数,返回值为整型数值。
实现Deque
class Deque:
def __init__(self):
self.items = []
def isEmpty(self):
return self.items == []
def addFront(self, item):
self.items.append(item)
def addRear(self, item):
self.items.insert(0,item)
def removeFront(self):
return self.items.pop()
def removeRear(self):
return self.items.pop(0)
def size(self):
return len(self.items)
if __name__ == '__main__':
d=Deque()
print(d.isEmpty())
d.addRear(4)
d.addRear('dog')
d.addFront('cat')
d.addFront(True)
print(d.size())
print(d.isEmpty())
d.addRear(8.4)
print(d.removeRear())
print(d.removeFront())
Deque的应用:回文词的判定
回文词指的是正读和反读都一样的词,如:radar、toot 和 madam。我们想要编写一个算法来检查放入的字符串是否为回文词。
from Deque import Deque
def palchecker(aString):
chardeque = Deque()
for ch in aString:
chardeque.addRear(ch)
stillEqual = True
while chardeque.size() > 1 and stillEqual:
first = chardeque.removeFront()
last = chardeque.removeRear()
if first != last:
stillEqual = False
return stillEqual
if __name__ == '__main__':
print(palchecker("lsdkjfskf"))
print(palchecker("aba"))
4、列表
列表是一些元素的集合,每个元素拥有一个与其它元素不同的相对位置。更具体地说,我们把这种类型的列表称为一个无序列表。我们可以认为列表有第一项、第二项、第三项……也可以索引到列表的开始(第一项)或列表的最后(最后一项)。为简单起见,我们假设列表不能包含重复项。
抽象数据类型无序列表 UNORDEREDLIST
无序列表结构是一个由各个元素组成的集合,在其中的每个元素拥有一个不
同于其它元素的相对位置。一些可用的无序列表的方法如下。
* list() 创建一个新的空列表。它不需要参数,而返回一个空列表。
*add(item) 将新项添加到列表,没有返回值。假设元素不在列表中。
*remove(item) 从列表中删除元素。需要一个参数,并会修改列表。此处假设元
素在列表中。
*search(item) 搜索列表中的元素。需要一个参数,并返回一个布尔值。
*isEmpty() 判断列表是否为空。不需要参数,并返回一个布尔值。
*size() 返回列表的元素数。不需要参数,并返回一个整数。
*append(item) 在列表末端添加一个新的元素。它需要一个参数,没有返回值。假设该项目不在列表中。
*index(item) 返回元素在列表中的位置。它需要一个参数,并返回位置索引值。此处假设该元素原本在列表中。
*insert(pos,item) 在指定的位置添加一个新元素。它需要两个参数,没有返回值。假设该元素在列表中并不存在,并且列表有足够的长度满足参数提供的索引需要。
*pop() 从列表末端移除一个元素并返回它。它不需要参数,返回一个元素。假设列表至少有一个元素。
*pop(pos) 从指定的位置移除列表元素并返回它。它需要一个位置参数,并返回一个元素。假设该元素在列表中。
采用链表实现无序列表
类:节点 NODE
用链表实现的基本模块是 节点。每个节点对象必须持有至少两条信息。首先,节点必须包含列表元素本身。我们将这称为该节点的“ 数据区”(data field)。此外,每个节点必须保持到下一个节点的引用。
# -*- coding:utf-8 -*-
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
# 返回列表大小
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
# 删除节点
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__':
temp = Node(93)
print(temp.getData())
mylist = UnorderedList()
mylist.add(31)
mylist.add(77)
mylist.add(17)
mylist.add(93)
mylist.add(26)
mylist.add(54)
print(mylist.search(17))
mylist.remove(17)
print(mylist.search(17))
抽象数据类型:有序列表
现在,我们考虑一类被称为有序列表的列表。例如,如果前文所示的整数列表是一个有序列表(升序),那么它可以写成 17,26,31,54,77 和 93。因为 17 是最小的,所以它是列表中的第一个元素。同样,因为 93 是最大的元素,它在列表中的位置是最后的。
OrderedList():创建一个新的空有序列表。它返回一个空有序列表并且不需要传递任何参数。
add(item):在保持原有顺序的情况下向列表中添加一个新的元素,新的元素作为参数传递进函数
而函数无返回值。假设列表中原先并不存在这个元素。
remove(item):从列表中删除某个元素。欲删除的元素作为参数,并且会修改原列表。假设原列表
中存在欲删除的元素。
search(item):在列表中搜索某个元素,被搜索元素作为参数,返回一个布尔值。
isEmpty():测试列表是否为空,不需要输入参数并且其返回一个布尔值。
size():返回列表中元素的数量。不需要参数,返回一个整数。
index(item):返回元素在列表中的位置。需要被搜索的元素作为参数输入,返回此元素的索引
值。假设这个元素在列表中。
pop():删除并返回列表中的最后一项。不需要参数,返回删除的元素。假设列表中至少有一个
元素。
pop(pos):删除并返回索引 pos 指定项。需要被删除元素的索引值作为参数,并且返回这个元
素。假设该元素在列表中。
实现有序列表
当我们考虑有序列表的方法时,我们应该注意到,isEmpty 和 size 方法的实现和无序列表相同,因为它们只处理列表中节点的数量而不考虑节点实际的值。同样,remove 方法也不需要改动,因为我们仍然需要找到某个节点然后删除它。但剩下的两个方法:search 和 add 需要一些修改。
class OrderedList:
def __init__(self):
self.head = None
def search(self, item):
current = self.head
found = False
stop = False
while current != None and not found and not stop:
if current.get_data() == item:
found = True
else:
if current.get_data() > item:
stop = True
else:
current = current.get_next()
return found
def add(self, item):
current = self.head
previous = None
stop = False
while current != None and not stop:
if current.get_data() > item:
stop = True
else:
previous = current
current = current.get_next()
temp = Node(item)
if previous == None:
temp.set_next(self.head)
self.head = temp
else:
temp.set_next(current)
previous.set_next(temp)