用Python實現的數據結構與算法:雙端隊列

1、概述

雙端隊列(deque,全名double-ended queue)是一種具備隊列和棧性質的線性數據結構。雙端隊列也擁有兩端:隊首(front)、隊尾(rear),但與隊列不一樣的是,插入操做在兩端(隊首和隊尾)均可以進行,刪除操做也同樣。html

2、ADT

雙端隊列ADT(抽象數據類型)通常提供如下接口:python

  • Deque() 建立雙端隊列
  • addFront(item) 向隊首插入項
  • addRear(item) 向隊尾插入項
  • removeFront() 返回隊首的項,並從雙端隊列中刪除該項
  • removeRear() 返回隊尾的項,並從雙端隊列中刪除該項
  • empty() 判斷雙端隊列是否爲空
  • size() 返回雙端隊列中項的個數

雙端隊列操做的示意圖以下:算法

雙端隊列操做

3、Python實現

在Python中,有兩種方式能夠實現上述的雙端隊列ADT:使用內建類型list、使用標準庫collections.deque(其實collections.deque就是Python中雙端隊列的標準實現)。markdown

兩種方式的不一樣主要體如今性能上(具體參考 collections.deque | TimeComplexity):數據結構

操做|實現方式   list    collections.deque
-----------------------------------------
addFront        O(n)    O(1)
-----------------------------------------
addRear         O(1)    O(1)
-----------------------------------------
removeFront     O(n)    O(1)
-----------------------------------------
removeRear      O(1)    O(1)

一、使用內建類型list

#!/usr/bin/env python
# -*- coding: utf-8 -*-

class Deque:
    def __init__(self):
        self.items = []

    def addFront(self, item):
        self.items.insert(0, item)

    def addRear(self, item):
        self.items.append(item)

    def removeFront(self):
        return self.items.pop(0)

    def removeRear(self):
        return self.items.pop()

    def empty(self):
        return self.size() == 0

    def size(self):
        return len(self.items)

二、使用標準庫collections.deque

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from collections import deque

class Deque:
    def __init__(self):
        self.items = deque()

    def addFront(self, item):
        self.items.appendleft(item)

    def addRear(self, item):
        self.items.append(item)

    def removeFront(self):
        return self.items.popleft()

    def removeRear(self):
        return self.items.pop()

    def empty(self):
        return self.size() == 0

    def size(self):
        return len(self.items)

4、應用

迴文(palindrome)是正讀反讀都同樣的單詞或句子,是一種修辭方式和文字遊戲。app

英文例子:性能

  • madam
  • able was i ere i saw elba

中文例子:code

  • 花非花
  • 人人爲我、我爲人人

若是要實現一個 迴文驗證算法(驗證一個給定的字符串是否爲迴文),使用Deque類將很是容易:將字符串存儲到雙端隊列,同時取出首尾字符並比較是否相等,只要有一對字符不等,則該字符串不是迴文;若所有相等,則該字符串爲迴文。具體代碼以下:htm

#!/usr/bin/env python
# -*- coding: utf-8 -*-

def palchecker(aString):
    chardeque = Deque()

    for ch in aString:
        chardeque.addRear(ch)

    while chardeque.size() > 1:
        first = chardeque.removeFront()
        last = chardeque.removeRear()
        if first != last:
            return False

    return True

if __name__ == '__main__':
    str1 = 'able was i ere i saw elba'
    print('"%s" is%s palindrome' % (str1, '' if palchecker(str1) else ' not'))

    str2 = u'人人爲我、我爲人人'
    print(u'"%s"%s是迴文' % (str2, u'' if palchecker(str2) else u'不'))

    str3 = u"What's wrong 怎麼啦"
    print(u'"%s"%s是迴文' % (str3, u'' if palchecker(str3) else u'不'))

運行結果:blog

$ python palchecker.py
"able was i ere i saw elba" is palindrome
"人人爲我、我爲人人"是迴文
"What's wrong 怎麼啦"不是迴文
相關文章
相關標籤/搜索