棧的特點是,先進後出,後進先出。只允許在一端插入和刪除資料。(想象往乙個桶裡放東西的過程)
如瀏覽器頁面的前進後退、函式呼叫都是用棧來實現的。
注:我們常說的資料結構裡「堆疊」其實就是「棧」,和「堆」是完全不同的概念。
'''用 python 的列表來實現乙個棧'''
class
stack
(object):
# 空列表作為初始化的棧
def__init__
(self)
: self.items =
# 判斷棧是否為空,返回布林值
defis_empty
(self)
:return self.items ==
# 返回棧頂元素
defpeek
(self)
:return self.items[
len(self.items)-1
]# 返回棧的大小
defsize
(self)
:return
len(self.items)
# 入棧
defpush
(self,item)
:# 出棧
defpop
(self)
:return self.items.pop(
)# pop()預設輸出最後乙個元素
佇列的特點是「先進先出」。類似排隊一樣,佇列有兩個操作:入隊enqueue(),放乙個資料到佇列尾部;出隊dequeue(),從佇列頭部取乙個元素。
普通佇列
"""用python列表實現乙個普通佇列"""
class
queue
(object):
# 用列表初始化空佇列
def__init__
(self,size)
: self.size = size
self.queue =
# 判斷空佇列
defis_empty
(self):if
len(self.queue)==0
:return
true
return
false
# 判斷滿佇列
defis_full
(self):if
len(self.queue)
== self.size:
return
true
return
false
# 入隊 enqueue
defenqueue
(self,item)
:if self.is_full():
return-1
# 出隊dequeue
defdequeue
(self,item)
:if self.is_empty():
return-1
first_element = self.queue[0]
self.queue.remove(first_element)
return first_element
雙端佇列
雙端佇列的隊頭和隊尾均可以實現入隊和出隊操作。
'''用python列表實現乙個雙端佇列'''
class
deque
(object):
# 用列表初始化佇列
def__init__
(self)
: self.deque =
# 判斷佇列是否為空
defis_empty
(self)
:return self.deque ==
# 返回佇列大小
defsize
(self)
:return
len(self.deque)
# 從隊頭插入資料
defpush_head
(self,item)
: self.deque.insert(
0,item)
# 從隊尾插入資料
defpush_tail
(self,item)
:# 從隊頭刪除資料
defpop_head
(self)
:return self.deque.pop(0)
# 從隊尾刪除資料
defpop_tail
(self)
:return self.deque.pop(
)
雙端佇列又分為,輸出受限佇列和輸入受限佇列。輸入受限佇列指的是,在佇列的一端可以實現插入和刪除操作,在另一端只能實現刪除操作;輸出受限佇列指的是,在佇列的一端可以實現插入和刪除操作,在另乙個段只能實現插入操作。如果限定佇列中從某個端點插入的的資料只能從該端點刪除,那這個佇列相當於兩個棧底相鄰的棧了。
優先佇列
優先佇列並不是像普通佇列一樣,按順序出隊或入隊。如下圖所示,如果是普通佇列,那麼資料5要比資料6出隊早。但是在優先佇列中,資料6比資料5大,則優先出隊。
迴圈佇列
簡單來講就是佇列的頭和尾連起來,就構成迴圈佇列。
把迴圈佇列畫成乙個圈更好理解。畫圖推導發現,當隊滿時,(tail+1)%n=head。其中,tail是尾指標,指向隊尾;head是頭指標,指向隊頭(圖中的front);n是佇列長度(以下**中用maxsize表示)。
"""用python實現迴圈佇列"""
class
circularqueue
(object):
def__init__
(self,maxsize)
: self.queue =
[none
]* maxsize # 給定長度
self.maxsize = maxsize
self.head =
0 self.tail =
0# 入隊dequeue,佇列未滿時在隊尾插入元素,時間複雜度時o(1)
defenqueue
(self,item):if
(self.tail +1)
% self.maxsize == self.head:
return-1
else
: self.queue[self.tail]
= item
self.tail =
(self.tail +1)
% self.maxsize
# 出隊dequeue,佇列不為空時刪除隊頭元素,時間複雜度o(1)
defdequeue
(self)
:if self.tail == self.head:
return-1
else
: item = self.queue[self.head]
self.queue[self.head]
=none
self.head =
(self.head +1)
% self.maxsize
return item
阻塞佇列和併發佇列
阻塞佇列就是在佇列基礎上增加了阻塞操作。隊列為空時,從對頭取資料會被阻塞,直到佇列中有資料才能返回;如果佇列滿了,插入的資料會被阻塞,直到佇列中有空閒位置後再插入資料,然後再返回。
併發佇列是指,執行緒安全的佇列。(多執行緒情況下,會有多個執行緒同時操作佇列,這時候就會存**程安全問題)
資料結構與演算法第 3 講 遞迴基礎
程式呼叫自身的程式設計技巧稱為遞迴 recursion 遞迴做為一種演算法在程式語言中廣泛應用。乙個過程或函式在其定義或說明中有直接或間接呼叫自身的一種方法,它通常把乙個大型複雜的問題層層轉化為乙個與原問題相似的規模較小的問題來求解,遞迴策略只需少量的程式就可描述出解題過程所需要的多次重複計算,大大...
佇列 棧(資料結構與演算法)
佇列是一種先進先出 fifo 的資料結構,從隊尾進,從隊頭出 在 fifo 資料結構中,將首先處理新增到佇列中的第乙個元素。如上圖所示,佇列是典型的 fifo 資料結構。插入 insert 操作也稱作入隊 enqueue 新元素始終被新增在佇列的末尾。刪除 delete 操作也被稱為出隊 deque...
資料結構與演算法(棧與佇列)
棧 stack 有些地方稱為堆疊,是一種容器,可存入資料元素 訪問元素 刪除元素,他的特點在於只能允許在容器的一端 稱為棧頂端指標,英語top 進行加入資料 英語push 和輸出資料 英語pop 的運算。沒有了位置概念,保證任何時候可以訪問 刪除的元素都是此前最後存入的那個元素,確定了一種預設的訪問...