數據結構 --- 01. 時間複雜度,timeit模塊,棧,隊列,雙端隊列

一.時間複雜度

 

  1.基本概念

評判程序優劣的方法:
  消耗計算機資源和執行效率(沒法直觀)
  計算算法執行的耗時(適當推薦,由於會受機器和執行環境的影響)
  時間複雜度(推薦)

 

時間複雜度
  評判規則:量化算法執行的操做
/執行步驟的數量   最重要的項:時間複雜度表達式中最有意義的項   大O記法:O(時間複雜度表達式中最有意義的項)

常見的時間複雜度:
  • O(1) < O(logn) < O(n) < O(nlogn) < O(n^2) < O(n^3) < O(2^n) < O(n!) < O(n^n)
 

 

  2.示例說明

python

a=5
b=6
c=10
for i in range(n):
   for j in range(n):
      x = i * i
      y = j * j
      z = i * j
for k in range(n):
   w = a*k + 45
   v = b*b
d = 33
3+3n**2+2n+1


用大O記法:
O(n**2)

 

web

def sumOfN(n):
    theSum = 0
    for i in range(0,n+1):
        theSum = theSum + i

    return theSum

print(sumOfN(10))
用大O記法:

O(n)

 

③三種不一樣數據結構的時間複雜度算法

[
    ['tom',100],['jay',99]
]
#O(n)
[
    ('tom',100),('jay',99)
]
#O(n)
{
    'tom':{'score':100},
    'jay':{'score':100},
}
#O(1)

 

 

二.timeit(測試代碼執行的平均值)

 

timeit模塊:該模塊能夠用來測試一段python代碼的執行速度/時長。
      計算運行平均耗時


Timer類:該類是timeit模塊中專門用於測量python代碼的執行速度/時長的。原型爲:class timeit.Timer(stmt='pass',setup='pass')。

  stmt參數:表示即將進行測試的代碼塊語句。

  setup:運行代碼塊語句時所須要的設置。

  timeit函數:timeit.Timer.timeit(number=100000),該函數返回代碼塊語句執行number次的平均耗時。

 

示例:實例化一個空列表,而後將0-n範圍的數據添加到列表中。
from timeit import Timer
def test01(): alist
= [] for i in range(1000): alist.append(i) def test02(): alist = [] for i in range(1000): alist += [i] def test03(): alist = [i for i in range(1000)] def test04(): alist = list(range(1000)) def test05(): alist = [] for i in range(1000): alist.insert(i,i) if __name__ == '__main__': timer = Timer(stmt='test01()',setup='from __main__ import test01') print(timer.timeit(1000)) timer = Timer(stmt='test02()',setup='from __main__ import test02') print(timer.timeit(1000)) timer = Timer(stmt='test03()',setup='from __main__ import test03') print(timer.timeit(1000)) timer = Timer(stmt='test04()',setup='from __main__ import test04') print(timer.timeit(1000)) timer = Timer(stmt='test05()',setup='from __main__ import test05') print(timer.timeit(1000))
結果:

0.0837575913687374
0.08196741393689422 0.03640777904436732 0.014782621075369207 0.16312698009613769

 

三.  棧

特性:先進後出的數據結構

 

 

  1.基本操做

Stack() 建立一個空的新棧。 它不須要參數,並返回一個空棧。
push(item)將一個新項添加到棧的頂部。它須要 item 作參數並不返回任何內容。
pop() 從棧中刪除頂部項。它不須要參數並返回 item 。棧被修改。
peek() 從棧返回頂部項,但不會刪除它。不須要參數。 不修改棧。
isEmpty() 測試棧是否爲空。不須要參數,並返回布爾值。
size() 返回棧中的 item 數量。不須要參數,並返回一個整數。

 

 

  2.示例:

瀏覽器

class Stack():
    def __init__(self):
        self.items = []
    def push(self,item):
        self.items.append(item)
    def pop(self):
        return self.items.pop()
    def peek(self):
        return self.items[-1]
    def isEmpty(self):
        return self.items == []
    def size(self):
        return len(self.items)

s = Stack()
s.push('jay')
s.push(123)
s.push('haha')
print(s.pop())
print(s.pop())
print(s.isEmpty())
print(s.size())
print(s.peek())
結果:

haha
123 False 1 jay

 

數據結構

應用:每一個 web 瀏覽器都有一個返回按鈕。當你瀏覽網頁時,這些網頁被放置在一個棧中(實際是網頁的網址)。

你如今查看的網頁在頂部,你第一個查看的網頁在底部。若是按‘返回’按鈕,將按相反的順序瀏覽剛纔的頁面。

 

s = Stack()
def request(url):
    s.push(url)
def back():
    return s.pop()
def current_page():
    print(s.pop())

request('www.1.com')
request('www.2.com')
request('www.3.com')

current_page()
back()
back()
結果:

www.3.com 'www.1.com'

 

四. 隊列

  1.基本概念

隊列:先進先出
應用場景:     咱們的計算機實驗室有
30 臺計算機與一臺打印機聯網。當學生想要打印時,
    他們的打印任務與正在等待的全部其餘打印任務「一致」。第一個進入的任務是先完成。
    若是你是最後一個,你必須等待你前面的全部其餘任務打印

 

 

  2.基本操做

Queue() 建立一個空的新隊列。 它不須要參數,並返回一個空隊列。
enqueue(item) 將新項添加到隊尾。 它須要 item 做爲參數,並不返回任何內容。
dequeue() 從隊首移除項。它不須要參數並返回 item。 隊列被修改。
isEmpty() 查看隊列是否爲空。它不須要參數,並返回布爾值。
size() 返回隊列中的項數。它不須要參數,並返回一個整數。

 

  3.示例

app

class Queue():
    def __init__(self):
        self.items = []
    def enqueue(self,item):
        self.items.insert(0,item)
    def dequeue(self):
        return self.items.pop()
    def isEmpty(self):
        return self.items == []
    def size(self):
        return len(self.items)
q = Queue()
q.enqueue(1)
q.enqueue(2)
q.enqueue(3)

print(q.dequeue())
print(q.dequeue())
結果:

1
2

 

 函數

案例:燙手的山芋
  燙手山芋遊戲介紹:6個孩子圍城一個圈,排列順序孩子們本身指定。
  第一個孩子手裏有一個燙手的山芋,須要在計時器計時1秒後將山芋傳遞給下一個孩子,
  依次類推。規則是,在計時器每計時7秒時,手裏有山芋的孩子退出遊戲。該遊戲直到剩下一個孩子時結束,
  最後剩下的孩子獲勝。請使用隊列實現該遊戲策略,排在第幾個位置最終會獲勝。

 

q = Queue()
alist = ['a','b','c','d','e','f']
for i in alist:
    q.enqueue(i)

while q.size() > 1:
    for i in range(6):
        kid = q.dequeue()
        q.enqueue(kid)
    q.dequeue()
    
print(q.dequeue())
結果:

    e

 

五,雙端隊列

同同列相比,有兩個頭部和尾部。能夠在雙端進行數據的插入和刪除,提供了單數據結構中棧和隊列的特性

 

 

  1.基本操做

Deque() 建立一個空的新 deque。它不須要參數,並返回空的 deque。
addFront(item) 將一個新項添加到 deque 的首部。它須要 item 參數 並不返回任何內容。
addRear(item) 將一個新項添加到 deque 的尾部。它須要 item 參數並不返回任何內容。
removeFront() 從 deque 中刪除首項。它不須要參數並返回 item。deque 被修改。
removeRear() 從 deque 中刪除尾項。它不須要參數並返回 item。deque 被修改。
isEmpty() 測試 deque 是否爲空。它不須要參數,並返回布爾值。
size() 返回 deque 中的項數。它不須要參數,並返回一個整數。

 

   2.示例:迴文檢查

雙端隊列應用案例:迴文檢查
迴文是一個字符串,讀取首尾相同的字符,例如,radar toot madam。

 

class Deque():
    def __init__(self):
        self.items = []
    def addFont(self,item):
        self.items.append(item)
    def addRear(self,item):
        self.items.insert(0,item)
    def removeFont(self):
        return self.items.pop()
    def removeRear(self):
        return self.items.pop(0)
    def isEmpty(self):
        return self.items == []
    def size(self):
        return len(self.items)
def isHuiWen(word):
    ex = True
    q = Deque()
    for ch in word:
        q.addFont(ch)
    while q.size() > 1:
        if q.removeFont() != q.removeRear():
            ex = False
            break
    return ex
print(isHuiWen('abbaa'))
結果:False
相關文章
相關標籤/搜索