init(初始化操作)
enquene(self,item) 若佇列存在,插入新元素item到佇列中,並成為隊尾元素
dequene(self) 刪除佇列中隊頭元素,並返回隊頭元素
思路:陣列實現佇列時,要注意,隨著不斷進隊,出隊,head和tail都會持續往後移動。當tail移動到最右邊,即使陣列中還有空餘空間,也無法繼續往佇列中新增元素了。這時可以用資料搬移。但是如果每一次出隊,都要搬移資料,時間複雜度就是0(n)。要讓時間複雜度盡可能變小,可以先在元素出隊時,不搬移資料。若沒有空間,再集中觸發一次搬移資料的操作。
from typing import optional
class arrayquene:
def __init__(self,capacity:int):
self.capacity=capacity
self.items=
self.head=0
self.tail=0
def enquene(self,item:str):
if self.tail==self.capacity:
return false
else:
#資料搬移
for i in range(0,self.tail-self.head):
self.items[i]=self.items[i+self.head]
self.tail=self.tail-self.head
self.head=0
#插入元素至隊尾,隊尾後移
self.items.insert(self.tail,item)
self.tail+=1
return true
def dequene(self):
# 若棧空
if self.head==self.tail:
return none
#若棧不為空
else:
#把隊頭元素從隊頭刪掉
item=self.items[self.head]
self.items.pop(self.head)
self.head-=1
return item
#展示給開發者,用於測試
def __repr__(self):
return " ".join(item for item in self.items[self.head:self.tail])
if __name__ == "__main__":
q=arrayquene(10)
for i in range(0,9):
q.enquene(str(i))
print (q)
q.enquene("3")
print(q)
q.dequene()
print(q)
print(q.items)
思路:
入隊時,是從鏈佇列尾部新增元素;出隊時,從鏈佇列的頭部刪除元素。入隊時,在鍊錶尾部插入結點。如果鍊錶尾部元素為空,那麼插入的元素就是第乙個元素。出隊時,頭結點的後繼指標出隊,將頭結點的後繼指標改為它後面的結點。
from typing import optional
class node:
def __init__(self, data: str, next=none):
self.data = data
self.next = next
class linkedqueue:
def __init__(self):
self.head: optional[node] = none
self.tail: optional[node] = none
def enqueue(self, value: str):
new_node = node(value)
#如果存在隊尾元素
if self.tail:
self.tail.next = new_node
else:
self.head = new_node
self.tail = new_node
def dequeue(self) -> optional[str]:
#如果存在對頭元素
if self.head:
value = self.head.data
self.head = self.head.next
if not self.head:
self.tail = none
return value
def __repr__(self) -> str:
values =
current = self.head
while current:
current = current.next
return "->".join(value for value in values)
if __name__ == "__main__":
q = linkedqueue()
for i in range(10):
q.enqueue(str(i))
print(q)
for _ in range(3):
q.dequeue()
print(q)
因為順序佇列需要做資料搬移,時間效能上有較大的的改進空間。迴圈佇列可以彌補順序佇列的不足。當有元素出隊有元素進隊,使得前面的頭指標所指的元素的下標不為0,頭結點前還有空位時,後面的元素直接插入頭結點前的空位,使得佇列頭尾相接。
問題在於:當head == tail時,隊列為空。那麼現在這種情況,如果佇列滿,我們發現head也可以是head == tail.
所以可以採取空餘乙個位置的辦法。
這種情況下,佇列滿的條件是(tail+1)%quenesize=head
長度為(tail+quenesize-head)%quenesize
from typing import optional
from itertools import chain
class circularqueue:
def __init__(self, capacity):
self._items =
self._capacity = capacity + 1
self._head = 0
self._tail = 0
def enqueue(self, item: str) -> bool:
if (self._tail + 1) % self._capacity == self._head:
return false
self._tail = (self._tail + 1) % self._capacity
return true
def dequeue(self) -> optional[str]:
if self._head != self._tail:
item = self._items[self._head]
self._head = (self._head + 1) % self._capacity
return item
def __repr__(self) -> str:
if self._tail >= self._head:
return " ".join(item for item in self._items[self._head : self._tail])
else:
return " ".join(item for item in chain(self._items[self._head:], self._items[:self._tail]))
if __name__ == "__main__":
q = circularqueue(5)
for i in range(5):
q.enqueue(str(i))
q.dequeue()
q.dequeue()
q.enqueue(str(5))
print(q)
資料機構與演算法分析讀書筆記 演算法分析
本章內容 演算法 algorithm 為求解乙個問題需要遵循的 被清楚指定的簡單指令的集合。ps 演算法的幾個特性這裡就不贅述。為了比較計算演算法的效能,需要一些正式的系統架構來計算演算法的效能,引入一些數學公式,用來比較 注 第一條定義的意義為t n 的相對增長率小於等於f n 的相對增長率。第二...
大資料學習之BigData常用演算法和資料結構
大資料學習之bigdata常用演算法和資料結構 1.bloom filter 由乙個很長的二進位制向量和一系列hash函式組成 優點 可以減少io操作,省空間 缺點 不支援刪除,有誤判 如果要支援刪除操作 改成計數布隆過濾器 2.skiplist 跳表 核心思路 由多層組成,每層都是乙個有序鍊錶,最...
演算法和資料結構學習筆記
演算法和資料結構就是程式設計的乙個重要部分,你若失掉了演算法和資料結構,你就把一切都失掉了。一 資料結構和演算法緒論 說說資料結構 程式設計 資料結構 演算法 再簡單來說,資料結構就是關係,也就是資料元素相互之間存在的一種或多種特定關係的集合。資料結構的分類 傳統上,我們把資料結構分為邏輯結構和物理...