学会思考
刻意练习
//链表的基本操作
//生成链表,插入结点,查找结点,删除结点,遍历链表,清空链表
//链表类模板

//LinkedList.h
#ifndef LINKEDLIST_H
#define LINKEDLIST_H
#include "Node.h"

template <class T> class LinkedList
{
private:
    Node<T> *front, *rear;//表头和表尾指针
    Node<T> *prevPtr, *currPtr;//记录表当前遍历位置的指针,由插入和删除操作更新
    int size;//表中的元素个数
    int position;//当前元素在表中的位置序号,由函数reset使用;
    //函数成员,生成新的结点,数据域为item,指针域为ptrNext
    Node<T> *newNode(const T &item, Node<T> *ptrNext = NULL);
    //释放结点
    void freeNode(Node<T> *p);
    //将链表L拷贝到当前表(假设当前表为空)
    void copy(const LinkedList<T> &L);
public:
    LinkedList();
    LinkedList(const LinkedList<T> &L);
    ~LinkedList();
    LinkedList<T> &operator = (const LinkedList<T> &L);

    int getSize() const;
    bool isEmpty() const;

    void reset(int pos = 0);
    void next();
    bool endOfList() const;
    int currentPosition() const;
    
    void insertFront(const T &item);
    void insertRear(const T &item);
    void insertAt(const T &item);
    void insertAfter(const T &item);

    T deleteFront();
    void deleteCurrent();

    T& data();
    const T& data() const;
    void clear();
};

template <class T> Node<T> *LinkedList<T>::newNode(const T &item, Node<T> *ptrNext)
{
    Node<T> *p;
    p = new Node<T>(item, ptrNext);
    if (p == NULL)
    {
        cout << "Memory alloction failure!\n";
        exit(1);
    }
    return p;
}

template <class T> void LinkedList<T>::freeNode(Node<T> *p)
{
    delete p;
}

template <class T> void LinkedList<T>::copy(const LinkedList<T> &L)
{
    Node<T> *p = L.front;
    int pos;
    while (p != NULL)
    {
        insertRear(p->data);
        p = p->nextNode();
    }
    if (position == -1)
        return;
    prevPtr = NULL;
    currPtr = front;
    for (pos = 0; pos != position; pos++)
    {
        prevPtr = currPtr;
        currPtr = currPtr->nextNode();
    }
}

template <class T> LinkedList<T>::LinkedList() :front(NULL), rear(NULL),
prevPtr(NULL), currPtr(NULL), size(0), position(-1)
{

}

template <class T> LinkedList<T>::LinkedList(const LinkList<T> &L)
{
    front = rear = NULL;
    prevPtr = currPtr = NULL;
    size = 0;
    position = -1;
    copy(L);
}

template <class T> LinkedList<T>::~LinkedList()
{
    clear();
}

template <class T> LinkedList<T>& LinkedList<T>::operator=(const LinkedList<T> &L)
{
    if (this == &L)
        return *this;
    clear();
    copy(L);
    return *this;
}

template <class T> int LinkedList<T>::getSize() const
{
    return size;
}

template <class T> bool LinkedList<T>::isEmpty() const
{
    return size == 0;
}


template <class T> void LinkedList<T>::reset(int pos)
{
    int startPos;
    if (front == NULL)
        return;
    if (pos < 0 || pos > size - 1)
    {
        std::cerr << "Reset: Invalid list position:" << pos << endl;
        return;
    }
    if (pos == 0)
    {
        prevPtr = NULL;
        currPtr = front;
        position = 0;
    }
    else
    {
        currPtr = front->nextNode();
        prevPtr = front;
        startPos = 1;
        for (postion = startPos; position != pos; position)
        {
            prevPtr = currPtr;
            currPtr = currPtr->nextNode();
        }
    }
}

template <class T> void LinkedList<T>::next()
{
    if (currPtr != NULL)
    {
        prevPtr = currPtr;
        currPtr = currPtr->nextNode();
        position++;
    }
}

template <class T> bool LinkedList<T>::endOfList() const
{
    return currPtr == NULL;
}

template <class T> int LinkedList<T>::insertFront(const T& item)
{
    if (front != NULL)
        reset();
    insertAt(item);
}

template <class T> void LinkedList<T>::insertRear(const T& item)
{
    Node<T> *node;
    prevPtr = rear;
    nNode = newNode(item);
    if (rear == NULL)
        front = rear = nNode;
    else
    {
        rear->insertAfter(nNode);
        rear = nNode;
    }
    currPtr = rear;
    position = size;
    size++;
}

template <class T> void LinkedList<T>::insertAt(const T& item)
{
    Node<T> *nNode;
    if (prevPtr == NULL)
    {
        nNode = newNode(item, front);
        front = nNode;
    }
    else
    {
        nNode = newNode(item);
        prevPtr->insertAfter(nNode);
    }
    if (prevPtr == rear)
    {
        rear = nNode;
        position = size;
    }
    currPtr = nNode;
    size++;
}

template <class T> void LinkedList<T>::insertAfter(const T& item)
{
    Node<T> *p;
    p = newNode(item);
    if (front == NULL)
    {
        front = currPtr = rear = 0;
        position = 0;
    }
    else
    {
        if (currPtr == NULL)
        {
            currPtr = prevPtr;
        }
        currPtr->insertAfter(p);
        if (currPtr == rear)
        {
            rear = p;
            position = size;
        }
        else
        {
            position++;
        }
        prevPtr = currPtr;
        currPtr = p;
    }
    size++;
}

template <class T> T LinkedList<T>::deleteFront()
{
    T item;
    reset();
    if (front == NULL)
    {
        cerr << "Invalid deletion!" << endl;
        exit(1);
    }
    item = currPtr->data;
    deleteCurrent();
    return item;
}

template <class T> void LinkedList<T>::deleteCurrent()
{
    Node<T> *p;
    if (currPtr == NULL)
    {
        cerr << "Invalid deletion !" << endl;
        exit(1);
    }
    if (prevPtr == NULL)
    {
        p = front;
        front = front->nextNode();
    }
    else
        p = prevPtr->deleteAfter();
    if (p == rear)
    {
        rear = prePtr;
        position--;
    }
    currPtr = p->nextNode();
    freeNode(p);
    size--;
}

template <class T> T & LinkedList<T>::data()
{
    if (size == 0 || currPtr == NULL)
    {
        cerr << "Data:invalid reference!" << endl;
        exit(1);
    }
    return currPtr->data;
}

template <class T> void LinkedList<T>::clear()
{
    Node<T> *currPosition, *nextPosition;
    currentPosition = front;
    while (currentPosition != NULL)
    {
        nextPosition = currentPosition->nextNode();
        freeNode(currentPosition);
        currentPosition = nextPosition;
    }
    front = rear = NULL;
    prevPtr = currPtr = NULL;
    size = 0;
    position = -1;
}

#endif // !LINKEDLIST_H

 

posted on 2017-03-15 21:13  Worty  阅读(574)  评论(0编辑  收藏  举报