用單鏈表實現棧 Push,Pop時間為O(1)
阿新 • • 發佈:2018-09-23
pri 時間 int 實現一個棧 我們 來看 一個棧 list() linked
用單鏈表實現一個棧,要求Push Pop的運行時間為O(1),來自《算法導論》習題10.2-2。
因為Push和Pop操作伴隨著棧頂元素的插入和刪除,所以,這個問題的本質是:在單鏈表的哪個位置進行插入和刪除,其運行時間為O(1)?初步來看,可能的選項有兩個,頭部和尾部。
又因為,要想在單鏈表上插入和刪除某個元素,必須先知道它在鏈表中的前驅和後繼。如果選擇尾部,那麽我們需要一直維護尾部元素的前驅和後繼,後繼節點是固定的(通常是哨兵節點),但是前驅節點的變化的,沒辦法在常量時間內拿到,所以這個方案不可行。
再來看,選擇頭部行不行呢?頭部節點的前驅是固定的,沒有問題,而它的後繼可以通過它的前驅索引到,時間是O(1)。所以我們選擇將單鏈表的頭部元素當做棧頂元素來實現這個棧。
下面是C++實現,單鏈表采用的是帶哨兵的循環鏈表形式。節點鍵值類型簡化為int。
class StackByLinkedList { public: StackByLinkedList(); ~StackByLinkedList(); void Push(int key); void Pop(); int Top() const; private: struct Node { Node* pNext; int key; }; Node m_sentinel; }; StackByLinkedList::StackByLinkedList() { m_sentinel.pNext = &m_sentinel; } StackByLinkedList::~StackByLinkedList() { Node* pCurrent = m_sentinel.pNext; Node* pNext = nullptr; while(pCurrent != &m_sentinel) { pNext = pCurrent->pNext; delete pCurrent; pCurrent = pNext; } } void StackByLinkedList::Push(int key) { Node* pNew = new Node; pNew->key = key; pNew->pNext = m_sentinel.pNext; m_sentinel.pNext = pNew; } void StackByLinkedList::Pop() { Node* pDelete = m_sentinel.pNext; if(pDelete == &m_sentinel) return; m_sentinel.pNext = pDelete->pNext; delete pDelete; } int StackByLinkedList::Top() const { Node* pTop = m_sentinel.pNext; return pTop == &m_sentinel ? -1 : pTop->key; }
用單鏈表實現棧 Push,Pop時間為O(1)