棧與隊(duì)列

棧(stack),有些地方稱(chēng)為堆棧,是一種容器,可存入數(shù)據(jù)元素、訪問(wèn)元素、刪除元素,它的特點(diǎn)在于只能允許在容器的一端(稱(chēng)為棧頂端指標(biāo),英語(yǔ):top)進(jìn)行加入數(shù)據(jù)(英語(yǔ):push)和輸出數(shù)據(jù)(英語(yǔ):pop)的運(yùn)算。沒(méi)有了位置概念,保證任何時(shí)候可以訪問(wèn)、刪除的元素都是此前最后存入的那個(gè)元素,確定了一種默認(rèn)的訪問(wèn)順序。
由于棧數(shù)據(jù)結(jié)構(gòu)只允許在一端進(jìn)行操作,因而按照后進(jìn)先出(LIFO, Last In First Out)的原理運(yùn)作。


棧結(jié)構(gòu)實(shí)現(xiàn)

棧可以用順序表實(shí)現(xiàn),也可以用鏈表實(shí)現(xiàn)。

棧的操作

  • Stack() 創(chuàng)建一個(gè)新的空棧
  • push(item) 添加一個(gè)新的元素item到棧頂
  • pop() 彈出棧頂元素
  • peek() 返回棧頂元素
  • is_empty() 判斷棧是否為空
  • size() 返回棧的元素個(gè)數(shù)

線性表都可以用來(lái)實(shí)現(xiàn)棧,棧只是一個(gè)容器,這里我們就用簡(jiǎn)單的順序表來(lái)實(shí)現(xiàn)棧,python中的順序表有哪幾種呢,我們直接用list來(lái)實(shí)現(xiàn)吧。

class Stack(object):
    '''棧'''
    def __init__(self):
        self.__list = []#首先建立這個(gè)容器
    def push(self,item):
    #添加一個(gè)新的元素item到棧頂,也就是壓棧
        return self.__list.append(item)
    def pop(self):
    #彈出棧頂元素
        return self.__list.pop()
    def peek(self):
    #返回棧頂元素
        if self.__list:
            return self.__list[-1]
        else:
            return None
    def is_empty(self):
    #判斷棧是否為空
        return self.__list == []
    def size(self):
        return len(self.__list)

if __name__ == '__main__':
    s = Stack()
    s.push(1)
    s.push(2)
    s.push(3)
    s.push(4)
    print(s.size())
    print(s.peek())
    print(s.pop())
    print(s.pop())
    print(s.pop())
    print(s.pop())

為什么我們使用從尾部取元素和壓棧呢,因?yàn)槲膊康臅r(shí)間復(fù)雜度為O(1),而如果是從頭部進(jìn)行取元素和壓棧,所需要的時(shí)間復(fù)雜度就是O(n)。

輸出如下:

4
4
4
3
2
1

說(shuō)完了這個(gè),說(shuō)一下隊(duì)列的問(wèn)題。

隊(duì)列

隊(duì)列(queue)是只允許在一端進(jìn)行插入操作,而在另一端進(jìn)行刪除操作的線性表。

隊(duì)列是一種先進(jìn)先出的(First In First Out)的線性表,簡(jiǎn)稱(chēng)FIFO。允許插入的一端為隊(duì)尾,允許刪除的一端為隊(duì)頭。隊(duì)列不允許在中間部位進(jìn)行操作!假設(shè)隊(duì)列是q=(A1,A2,……,An),那么A1就是隊(duì)頭元素,而An是隊(duì)尾元素。這樣我們就可以刪除時(shí),總是從A1開(kāi)始,而插入時(shí),總是在隊(duì)列最后。這也比較符合我們通常生活中的習(xí)慣,排在第一個(gè)的優(yōu)先出列,最后來(lái)的當(dāng)然排在隊(duì)伍最后。

隊(duì)列的實(shí)現(xiàn)

同棧一樣,隊(duì)列也可以用順序表或者鏈表實(shí)現(xiàn)。

操作

  • Queue() 創(chuàng)建一個(gè)空的隊(duì)列
  • enqueue(item) 往隊(duì)列中添加一個(gè)item元素
  • dequeue() 從隊(duì)列頭部刪除一個(gè)元素
  • is_empty() 判斷一個(gè)隊(duì)列是否為空
  • size() 返回隊(duì)列的大小
class Queue(object):
    '''隊(duì)列'''
    def __init__(self):
        self.__list = []
    def enqueue(self,item):
        '''往隊(duì)列中添加一個(gè)item元素'''
        return self.__list.append(item)
        #return self.__list.insert(0,item)

    def dequeue(self):
        '''從隊(duì)列頭部刪除一個(gè)元素'''
        return self.__list.pop(0)
        #return self.__list.pop() pop()沒(méi)參數(shù)默認(rèn)是隊(duì)尾

    def is_empty(self):
        '''判斷一個(gè)隊(duì)列是否為空'''
        return self.__list == []

    def size(self):
        '''返回隊(duì)列的大小'''
        return len(self.__list)

if __name__ == '__main__':
    s = Queue()
    s.enqueue(1)
    s.enqueue(2)
    s.enqueue(3)
    s.enqueue(4)
    print('*'*20)
    print(s.dequeue())
    print(s.dequeue())
    print(s.dequeue())
    print(s.dequeue())

因?yàn)樯婕暗絻蓚€(gè)通道,一頭壓棧,一頭出棧,所以總會(huì)有一頭的時(shí)間復(fù)雜度是O(n),一個(gè)是O(1)。
輸出結(jié)果如下:

********************
1
2
3
4

雙端隊(duì)列

雙端隊(duì)列(deque,全名double-ended queue),是一種具有隊(duì)列和棧的性質(zhì)的數(shù)據(jù)結(jié)構(gòu)。

雙端隊(duì)列中的元素可以從兩端彈出,其限定插入和刪除操作在表的兩端進(jìn)行。雙端隊(duì)列可以在隊(duì)列任意一端入隊(duì)和出隊(duì)。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容