| |
| #ifndef NODE_H |
| #define NODE_H |
| |
| |
| template <class T> |
| class Node { |
| private: |
| Node<T> *next; |
| public: |
| T data; |
| |
| Node (const T &data, Node<T> *next = 0); |
| void insertAfter(Node<T> *p); |
| Node<T> *deleteAfter(); |
| Node<T> *nextNode(); |
| const Node<T> *nextNode() const; |
| }; |
| |
| |
| |
| template <class T> |
| Node<T>::Node(const T& data, Node<T> *next) : data(data), next(next) { } |
| |
| |
| template <class T> |
| Node<T> *Node<T>::nextNode() { |
| return next; |
| } |
| |
| |
| template <class T> |
| const Node<T> *Node<T>::nextNode() const { |
| return next; |
| } |
| |
| |
| template <class T> |
| void Node<T>::insertAfter(Node<T> *p) { |
| p->next = next; |
| next = p; |
| } |
| |
| |
| template <class T> |
| Node<T> *Node<T>::deleteAfter() { |
| Node<T> *tempPtr = next; |
| if (next == 0) |
| return 0; |
| next = tempPtr->next; |
| return tempPtr; |
| } |
| |
| #endif |
| |
| #ifndef LINKEDLIST_H |
| #define LINKEDLIST_H |
| #include "Node.h" |
| |
| #include<iostream> |
| using namespace std; |
| |
| template <class T> |
| class LinkedList { |
| private: |
| |
| Node<T> *front, *rear; |
| Node<T> *prevPtr, *currPtr; |
| int size; |
| int position; |
| |
| |
| |
| Node<T> *newNode(const T &item,Node<T> *ptrNext=NULL); |
| |
| |
| void freeNode(Node<T> *p); |
| |
| |
| |
| 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 allocation 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 LinkedList<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) |
| { |
| 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 (position = 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>::currentPosition() const |
| { |
| return position; |
| } |
| |
| template <class T> |
| void LinkedList<T>::insertFront(const T& item) |
| { |
| if (front != NULL) |
| reset(); |
| insertAt(item); |
| } |
| |
| |
| template <class T> |
| void LinkedList<T>::insertRear(const T& item) |
| { |
| Node<T> *nNode; |
| 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 = p; |
| 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 = prevPtr; |
| 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; |
| currPosition = front; |
| while (currPosition != NULL) |
| { |
| nextPosition = currPosition->nextNode(); |
| freeNode(currPosition); |
| currPosition = nextPosition; |
| } |
| front = rear = NULL; |
| prevPtr = currPtr = NULL; |
| size = 0; |
| position = -1; |
| } |
| |
| |
| #endif |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~