(Python3)數據結構——08.隊列之用隊列實現一個棧

前言

  • 有Python基礎
  • 最好是學過數據結構的棧和隊列
  • 參考鏈接
隊列:https://blog.csdn.net/sf9898/article/details/104941655
棧:https://blog.csdn.net/sf9898/article/details/104939489

原理

  • 提出這樣的一個問題,如何用隊列去模擬棧,或者說,用隊列實現棧的效果,即先進後出?
  • 隊列和棧的區別無非是先進先出和先進後出,那麼在之前的博客中,二者的數據存儲都是用的list類型,入隊和入棧都是從list類型的items的尾部進去的,即採用append的方法。區別在於出的情況。隊列是從頭出,用的是pop(0),彈出items的第一個元素,棧是用的pop(),刪除items最後一個元素。如果進行模擬,那麼需要對這一點進行模擬。

實現

隊列的類

  • 首先先去寫隊列的類
class Queue(object):
    def __init__(self):
        self.items = []

    def isEmpty(self):
        return len(self.items) == 0

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

    def travel(self):
        for i in self.items:
            print(i, end=' ')
        print('')

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

    # 這個是原來的pop函數,更名爲pop1
    def pop1(self):
        self.items.pop(0)

    # 需要改造下pop函數,使得這個函數有返回值
    def pop(self):
        return self.items.pop(0)

一個隊列

  • 假設用一個隊列實現,那麼可以將出隊的元素加到隊尾,之後一個一個進行此項操作,當發現是原來的最後一個元素時,將其刪除,並打印它的值。因此需要有刪除的函數和返回這個數值的函數。刪除完原來的最後一個,那麼開始刪原來的倒數第二個…以此類推。完整代碼如下。
class Queue(object):
    def __init__(self):
        self.items = []

    def isEmpty(self):
        return len(self.items) == 0

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

    def travel(self):
        for i in self.items:
            print(i, end=' ')
        print('')

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

    # 這個是原來的pop函數,更名爲pop1
    def pop1(self):
        self.items.pop(0)

    # 需要改造下pop函數,使得這個函數有返回值
    def pop(self):
        return self.items.pop(0)


# 隊列的基本功能的測試
q = Queue()
print(q.isEmpty())  # 應是True
for i in range(5):
    q.push(i)
q.travel()  # 0 1 2 3 4
for i in range(3):
    q.pop1()
q.travel()  # 3 4
print(q.size())  # 2
print('----------')
# 隊列是先進先出,棧是先進後出
# 都是從尾加入,隊列是從頭出,棧是從尾出,因此需要針對出的這一塊進行模擬
q1 = Queue()
# 進的方式是一樣的,下面初始化一下
for i in range(20):
    q1.push(i)
print('隊列的出隊順序:', end=' ')
q1.travel()
# 假設只用一個棧,要使得輸出的序列反過來(既要完成“出”的任務還要保證打印順序)
# q1 出隊的數加到末尾
N = q1.size()
print('棧的出棧順序:  ', end=' ')
# 下面的循環:第一次要把最後一個數移到開頭需要進行N-1次,然後扔掉這個數,現在items的長度剩下N-1,
# 那麼下一次將最後一個元素(即原來的倒數第二個元素)移到開頭需要進行N-1-1即N-2次...
for j in range(1, N + 1):
    for i in range(N - j):
        q1.push(q1.pop())
    print(q1.items[0], end=' ')  # 打印一下當前的開頭
    q1.pop1()  # 然後取出這個出頭鳥
  • 結果

在這裏插入圖片描述

兩個隊列

  • 假設用兩個隊列呢?假設q1不爲空,q2是空的,那麼可以將q1彈出元素直至只剩下最後一個元素,彈出的元素均加入到q2中,那麼此時將q1中的元素彈出並打印。之後q1是一個空的隊列,q2中裝的是之前q1彈出的元素,即第一個元素到倒數第二個元素。此時將q1,q2交換,繼續重複之前的操作,可以一個個彈出並打印出想要的結果,實現棧的先進後出的效果。代碼如下。
class Queue(object):
    def __init__(self):
        self.items = []

    def isEmpty(self):
        return len(self.items) == 0

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

    def travel(self):
        for i in self.items:
            print(i, end=' ')
        print('')

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

    # 這個是原來的pop函數,更名爲pop1
    def pop1(self):
        self.items.pop(0)

    # 需要改造下pop函數,使得這個函數有返回值
    def pop(self):
        return self.items.pop(0)


# 隊列的基本功能的測試
q = Queue()
print(q.isEmpty())  # 應是True
for i in range(5):
    q.push(i)
q.travel()  # 0 1 2 3 4
for i in range(3):
    q.pop1()
q.travel()  # 3 4
print(q.size())  # 2
print('----------')

# 假設是用兩個隊列實現一個棧呢?
q1 = Queue()
q2 = Queue()
for i in range(10):
    q1.push(i)
print('隊列的出隊順序:', end=' ')
q1.travel()
print('棧的出棧順序是:', end=' ')
while q1.size():
    while q1.size() > 1:
        # 出來的數先存到q2中,僅留一個數
        item = q1.pop()
        q2.push(item)
    # 將僅留下的這個數出隊並打印
    print(q1.pop(), end=' ')
    # 之後把兩個隊列互換
    q1, q2 = q2, q1
  • 結果

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章