码迷,mamicode.com
首页 > 其他好文 > 详细

用单链表实现栈 Push,Pop时间为O(1)

时间:2018-09-23 18:17:48      阅读:459      评论:0      收藏:0      [点我收藏+]

标签:算法   删除   插入   amp   ptr   ++   vat   let   ret   

  • 用单链表实现一个栈,要求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)

标签:算法   删除   插入   amp   ptr   ++   vat   let   ret   

原文地址:https://www.cnblogs.com/meixiaogua/p/9692930.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!