python 数据结构 双端队列的两种实现方式 list 和 DoublelinkedList 回文词验证
1. python内置list实现 我们知道list 是由数组实现的 insert O(n) append O(1)
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) def palchecker(aString): chardeque = Deque() for ch in aString.replace(" ",""): chardeque.addRear(ch) stillEqual = True print(aString) while chardeque.size() > 1 and stillEqual: first = chardeque.removeFront() last = chardeque.removeRear() if first != last: stillEqual = False return stillEqual print(palchecker('radar')) print(palchecker('r a da r'))
运行结果:
2.双链表实现,我们这里就不用单指针了,添加首尾指针,这样两边的进出复杂度都为O(1)
class Node: def __init__(self, key, value): self.key = key self.value = value self.prev = None self.next = None def __str__(self): val = '{%s: %s}' % (self.key, self.value) return val def __repr__(self): val = '{%s: %s}' % (self.key, self.value) return val class DoubleLinkedList: def __init__(self, capacity=0xffff): self.capacity = capacity # 链表容量 self.head = None # 头部节点 self.tail = None # 尾部节点 self.size = 0 # 保存当前列表已经存储了多少个节点 # 从头部添加 def __add_head(self, node): if not self.head: # 判断链表头部节点是否空,如果是,说明当前节点是头部节点 self.head = node self.tail = node self.head.next = None self.head.prev = None else: # 否则,把当前节点指向现在的头部,上一个节点指向当前的节点 node.next = self.head self.head.prev = node self.head = node self.head.prev = None self.size += 1 return node # 从尾部添加 def __add_tail(self, node): if not self.tail: self.tail = node self.head = node self.tail.next = None self.tail.prev = None else: self.tail.next = node node.prev = self.tail self.tail = node self.tail.next = None self.size += 1 return node # 从尾部删除 def __del_tail(self): if not self.tail: return node = self.tail if node.prev: self.tail = node.prev self.tail.next = None else: self.tail = self.head = None self.size -= 1 return node # 从头部删除 def __del_head(self): if not self.head: return node = self.head if node.next: self.head = node.next self.head.prev = None else: self.tail = self.head = None self.size -= 1 return node # 删除任意节点 def __remove(self, node): # 如果node=None, 默认删除尾部节点 if not node: node = self.tail if node == self.tail: self.__del_tail() elif node == self.head: self.__del_head() else: node.prev.next = node.next node.next.prev = node.prev self.size -= 1 return node # 弹出头部节点 def pop(self): return self.__del_head() def pop0(self): return self.__del_tail() # 添加节点 def append(self, node): return self.__add_tail(node) # 从头部添加节点 def append_front(self, node): return self.__add_head(node) # 删除节点 def remove(self, node=None): return self.__remove(node) # 打印当前列表 def print(self): p = self.head line = '' while p: line += '%s' % p p = p.next if p: line += '<-->' print(line) def palchecker(aString): chardeque = DoubleLinkedList() for ch in aString.replace(" ",""): ch = Node(key='key', value=ch) chardeque.append(ch) stillEqual = True print(aString) chardeque.print() while chardeque.size > 1 and stillEqual: first = chardeque.pop() last = chardeque.pop0() if first.value != last.value: stillEqual = False return stillEqual if __name__ == '__main__': I =DoubleLinkedList(10) nodes = [] for i in range(10): node = Node(i, i) nodes.append(node) I.append(nodes[0]) I.print() I.append(nodes[1]) I.print() I.pop() I.print() I.append(nodes[2]) I.print() I.append_front(nodes[3]) I.print() I.append(nodes[4]) I.print() I.remove(nodes[2]) I.print() I.remove() I.print() print(palchecker('radar')) print(palchecker('r ad a r'))
运行结果 可发现两种实现方式都可以实现回文词功能:这里print和内置的__str__更加直观地显示了双链表的结构。