单链表逆转问题

  • 实现对含有n个元素的单链表的逆转,要求运行时间O(n),除了链表本身所需空间外,只使用固定大小的存储空间。(此题来自《算法导论》10.2-7)

    从头元素开始循环,将原本指向其后继节点的指针指向其前驱节点,直到循环至哨兵为止。整个过程额外需要三个指针变量的空间,分别保存当前节点及其前驱、后继。

    下面是一个简单的C++实现。

struct Node
{
    Node* pNext;
    int key;
};

class SingleLinkedList
{
public:
    SingleLinkedList();
    ~SingleLinkedList();
    void Insert(int key);
    void Traverse() const;
    void Invert();
private:
    Node m_sentinel;
};

SingleLinkedList::SingleLinkedList()
{
    m_sentinel.pNext = &m_sentinel;
}

SingleLinkedList::~SingleLinkedList()
{
    Node* pCurrent = m_sentinel.pNext;
    Node* pNext = nullptr;
    while(pCurrent != &m_sentinel)
    {
        pNext = pCurrent->pNext;
        delete pCurrent;
        pCurrent = pNext;
    }
}

void SingleLinkedList::Insert(int key)
{
    Node* pNew = new Node;
    pNew->pNext = m_sentinel.pNext;
    pNew->key = key;
    m_sentinel.pNext = pNew;
}

void SingleLinkedList::Traverse() const
{
    Node* pCurrent = m_sentinel.pNext;
    while(pCurrent != &m_sentinel)
    {
        cout << pCurrent->key << '\t';
        pCurrent = pCurrent->pNext;
    }
}

void SingleLinkedList::Invert()
{
    Node* pPrevious = &m_sentinel;
    Node* pCurrent = m_sentinel.pNext;
    Node* pNext = nullptr;
    while(pCurrent != &m_sentinel)    //每一步循环修改当前节点的pNext属性,并将pPrevious pCurrent pNext 都向后移一位
    {
        pNext = pCurrent->pNext;
        pCurrent->pNext = pPrevious;
        pPrevious = pCurrent;
        pCurrent = pNext;
    }
    pCurrent->pNext = pPrevious;
}

int main()    //测试代码
{
    SingleLinkedList* p = new SingleLinkedList;
    for(int i = 0; i != 10; ++i)
        p->Insert(i);
    p->Traverse(); cout << endl; //9,8,7...0
    p->Invert();
    p->Traverse(); cout << endl; //  0,1,2...9
    delete p; p = nullptr;
    return 0;
}

//输出结果
9 8 7 6 5 4 3 2 1 0
0 1 2 3 4 5 6 7 8 9

猜你喜欢

转载自www.cnblogs.com/meixiaogua/p/9695180.html