隊列 和 堆棧用python 來實現


一、利用python列表實現堆棧和隊列

堆棧:

堆棧是一個后進先出的數據結構,其工作方式就像生活中常見到的直梯,先進去的人肯定是最后出。

我們可以設置一個類,用列表來存放棧中的元素的信息,利用列表的append()和pop()方法可以實現棧的出棧pop和入棧push的操作,list.append(obj)意思是向列表添加一個對象obj,list.pop(index=-1)意思是刪除指定位置的對象,默認是最后一個對象,也就是說list.pop(),是刪除列表中下標最大的元素。

# 后進先出
class Stack():
    def __init__(self,size):
        self.size=size
        self.stack=[]
        self.top=-1

    def push(self,x):  # 入棧之前檢查棧是否已滿
        if self.isfull():
            raise exception("stack is full")
        else:
            self.stack.append(x)
            self.top=self.top+1

    def pop(self):  # 出棧之前檢查棧是否為空
        if self.isempty():
            raise exception("stack is empty")
        else:
            self.top=self.top-1
            self.stack.pop()

    def isfull(self):
        return self.top+1 == self.size
    def isempty(self):
        return self.top == '-1'
    def showStack(self):
        print(self.stack)

s=Stack(10)
for i in range(6):
    s.push(i)
s.showStack()
for i in range(3):
    s.pop()
s.showStack()

"""
類中有top屬性,用來指示棧的存儲情況,初始值為1,一旦插入一個元素,其值加1,利用top的值樂意判定棧是空還是滿。
執行時先將0,1,2,3,4,5依次入棧,然后刪除棧頂的前三個元素
"""
View Code

基本FIFO隊列

class Queue.Queue(maxsize=0)

FIFO即First in First Out,先進先出。Queue提供了一個基本的FIFO容器,使用方法很簡單,maxsize是個整數,指明了隊列中能存放的數據個數的上限。一旦達到上限,插入會導致阻塞,直到隊列中的數據被消費掉。如果maxsize小於或者等於0,隊列大小沒有限制。

舉個栗子:

import Queue

q = Queue.Queue()   # 建一個隊列 先進先出

for i in range(5):      # 放五個元素進去
    q.put(i)

while not q.empty(): # 當隊列不為空時,循環取值
    print q.get()

輸出:

0
1
2
3
4

LIFO隊列

class Queue.LifoQueue(maxsize=0)

LIFO即Last in First Out,后進先出。與棧的類似,使用也很簡單,maxsize用法同上

再舉個栗子:

import Queue

q = Queue.LifoQueue()  # 建一個后進先出的隊列

for i in range(5):           # 放五個值進去
    q.put(i)

while not q.empty():     # 循環全部取出所有值
    print q.get() 

輸出 :

4
3
2
1
0

優先級隊列

class Queue.PriorityQueue(maxsize=0)

構造一個優先隊列。maxsize用法同上。

 

 

 

 

隊列:

隊列是一種先進先出的數據類型,它的跟蹤原理類似於在超市收銀處排隊,隊列里的的第一個人首先接受服務,
新的元素通過入隊的方式添加到隊列的末尾,而出隊就是將隊列的頭元素刪除。
我們可以設置一個類,用列表來存放棧中元素的信息,利用列表的append()和pop()方法可以實現隊列的入隊enqueue和出隊dequeue的操作,
上面棧一個元素每次出去是列表的最后一個,直接用list.pop()出棧,而出隊列每次是第一個,所以要用list.pop(0)出隊列
# 先進先出
class Queue():

    def __init__(self,size):
        self.size=size
        self.front=-1
        self.rear=-1
        self.queue=[]

    def enqueue(self,ele):  # 入隊操作
        if self.isfull():
            raise exception("queue is full")
        else:
            self.queue.append(ele)
            self.rear=self.rear+1

    def dequeue(self):  # 出隊操作
        if self.isempty():
            raise exception("queue is empty")
        else:
            self.queue.pop(0)
            self.front=self.front+1

    def isfull(self):
        return self.rear-self.front+1 == self.size
    def isempty(self):
        return self.front == self.rear
    def showQueue(self):
        print(self.queue)

q=Queue(10)
for i in range(6):
    q.enqueue(i)
q.showQueue()
for i in range(3):
    q.dequeue()
q.showQueue()
print(q.isempty())

"""
類中設置兩個屬性分別為front和rear來模擬隊列的頭尾指針,通過它們值的關系可以判定隊列是空還是滿
"""
View Code

一些常用方法

task_done()

意味着之前入隊的一個任務已經完成。由隊列的消費者線程調用。每一個get()調用得到一個任務,接下來的task_done()調用告訴隊列該任務已經處理完畢。

如果當前一個join()正在阻塞,它將在隊列中的所有任務都處理完時恢復執行(即每一個由put()調用入隊的任務都有一個對應的task_done()調用)。

join()

阻塞調用線程,直到隊列中的所有任務被處理掉。

只要有數據被加入隊列,未完成的任務數就會增加。當消費者線程調用task_done()(意味着有消費者取得任務並完成任務),未完成的任務數就會減少。當未完成的任務數降到0,join()解除阻塞。

put(item[, block[, timeout]])

將item放入隊列中。

  1. 如果可選的參數block為True且timeout為空對象(默認的情況,阻塞調用,無超時)。
  2. 如果timeout是個正整數,阻塞調用進程最多timeout秒,如果一直無空空間可用,拋出Full異常(帶超時的阻塞調用)。
  3. 如果block為False,如果有空閑空間可用將數據放入隊列,否則立即拋出Full異常

其非阻塞版本為put_nowait等同於put(item, False)

get([block[, timeout]])

從隊列中移除並返回一個數據。block跟timeout參數同put方法

其非阻塞方法為`get_nowait()`相當與get(False)

empty()

如果隊列為空,返回True,反之返回False


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM