#include<iostream>
using namespace std;
template<class T>
class Node
{
private:
Node<T> * next;
public:
T data; //数据域
Node(const T & data, Node<T> * next = 0) :data(data), next(next) {} //构造函数
void InsertAfter(Node<T> *p) { //在本结点之后插入一个同类结点P
p->next = next;
next = p;
}
Node<T> *DeleteAfter() { //删除本结点的后继结点,并返回其地址
Node<T>* tempp = next;
if (next == 0) //如果当前结点没有后继结点,则反回空指针
return 0;
next = tempp->next;
return tempp; //返回被删除的结点的地址
}
Node<T> *NextNode() { return next; } //获取后继结点的地址
const Node<T>* NextNode()const { return next; } //获取后继结点的地址
~Node() {}
};
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) {
Node<T> *newNode;
newNode = new Node<T>(item, ptrNext);
if (newNode == NULL) {
cout << "Memory allocation failure!" << endl;
exit(1);
}
return newNode;
}
// 释放结点
void FreeNode(Node<T> *p) {
delete p;
}
// 将链表 L 拷贝到当前表(假设当前表为空)。
// 被复制构造函数和“operator =”调用
void Copy(const LinkedList<T> &L) {
if (L.size == 0)
return;
front = rear = NewNode(L.front->data,NULL);
for (Node<T> *srcNode = L.front->NextNode();
srcNode != NULL;
srcNode = srcNode->NextNode())
{
Node<T> *newNode = NewNode(srcNode->data,NULL);
rear->InsertAfter(newNode);
rear = newNode;
}
size = L.size;
}
public:
//默认构造函数-空
LinkedList(void) : front(NULL), rear(NULL), prevPtr(NULL), currPtr(NULL), size(0), position(0) {}
LinkedList(const LinkedList<T> &L) : front(NULL), rear(NULL), prevPtr(NULL), currPtr(NULL), size(0), position(0) { Copy(L); }//复制构造函数
~LinkedList(void) {//析构函数
Clear();
}
LinkedList<T>& operator =(const LinkedList<T> &L) { // 重载赋值运算符
Clear();
Copy(L);
return *this;
}
int GetSize(void) const { // 返回链表中元素个数
return size;
}
bool IsEmpty(void) const { // 链表是否为空
return (size == 0);
}
/**
@brief 初始化游标的位置
@param pos 从零计起的位置编号
@note pos 无限制
当 pos 在 0 和 size 之间时,prevPtr 和 currPtr 正常指示;
当 pos 为 0 时,prevPtr = NULL, currPtr = front;
当 pos 为 size 时,prevPtr = rear, currPtr = NULL;
当 pos 取其他值时,prevPtr = currPtr = NULL。
*/
void Reset(int pos = 0) { // 初始化游标的位置
if (0 <= pos && pos <= size) {
position = 0;
prevPtr = NULL;
currPtr = front;
// 游标回到头结点,再逐步前移
while (pos--)
Next();
}
else {
position = pos;
prevPtr = NULL;
currPtr = NULL;
}
}
void Next(void) {
if (currPtr != NULL) { // 使游标移动到下一个结点
position++;
prevPtr = currPtr;
currPtr = currPtr->NextNode();
}
}
/**
@brief 游标是否到了链尾
@return 游标是否到了链尾
游标“到了链尾”意即游标“超出了链表”,
当游标所示的当前结点不存在时即判断到了链尾。
*/
bool EndOfList(void) const {
return (currPtr == NULL);
}
/**
@brief 返回游标当前的位置
@return 从零计起的位置编号
@note 游标可以在链表之外
*/
int CurrentPosition(void) {
Node<T>*tempPtr = front;
position = 0;
while (tempPtr != currPtr)
{
tempPtr = tempPtr->NextNode();
position++;
}
return position;
}
void InsertFront(const T &item) { // 在表头插入结点
front = NewNode(item, front);
if (IsEmpty())
rear = front;
size++;
}
void InsertRear(const T &item) { // 在表尾插入结点
Node<T> *newNode = NewNode(item);
if (IsEmpty()) {
front = rear = newNode;
}
else {
rear->InsertAfter(newNode);
rear = newNode;
}
size++;
}
/**
@brief 在当前结点之前插入结点
@param item 新结点的数据域
@note 只考虑当前位置的结点存在的情况
*/
void InsertBefore(const T &item) {
if (currPtr != NULL) {
Node<T> *newNode = GetNode(item, currPtr);
if (prevPtr != NULL)
prevPtr->InsertAfter(newNode);
else
front = prevPtr = newNode;
size++;
}
}
/**
@brief 在当前结点之后插入结点
@param item 新结点的数据域
@note 只考虑当前位置的结点存在的情况
*/
void InsertAfter(const T &item) {
if (currPtr != NULL) {
Node<T> *newNode = NewNode(item, currPtr->NextNode());
currPtr->InsertAfter(newNode);
if (rear == currPtr)
rear = newNode;
size++;
}
}
T DeleteFront(void) { // 删除头结点,并返回所删除结点的data
if (IsEmpty()) {
cout << "List is empty, delete error." << endl;
exit(1);
}
Node<T> *delNode = front;
front = front->NextNode();
size--;
if (size == 0)
rear = NULL;
T item = delNode->data;
FreeNode(delNode);
return item;
}
void DeleteCurrent(void) { // 删除当前结点
if (currPtr != NULL) {
if (front == currPtr)
front = currPtr->NextNode();
if (rear == currPtr)
rear = prevPtr;
if (prevPtr != NULL)
prevPtr->DeleteAfter();
FreeNode(currPtr);
size--;
}
}
T& Data(void) { // 返回对当前结点成员数据的引用
if (currPtr == NULL) {
cout << "Current node is invalid." << endl;
exit(1);
}
return currPtr->data;
}
const T& Data(void) const { // 返回对当前结点成员数据的常引用
if (currPtr == NULL) {
cout << "Current node is invalid." << endl;
exit(1);
}
return currPtr->data;
}
// 清空链表:释放所有结点的内存空间。被析构函数和“operator =”调用
void Clear(void) {
while (!IsEmpty())
DeleteFront();
}
};
int main() {
LinkedList<int> linklist;
for (int i = 0; i < 10; i++) {
int x;
cin >> x;
linklist.InsertFront(x);
//cout << linklist.CurrentPosition() << endl;
}
cout << "链表输出:" << endl;
linklist.Reset(0);
while (!linklist.EndOfList()) {
cout << linklist.Data() << endl;
linklist.Next();
}
cout << endl;
//接下来取出第10个元素
linklist.Reset(9);
cout << "取出的第10个元素为:" << endl;
cout << linklist.Data() << endl;
//接下来复制链表
LinkedList<int> linklist_copy;
linklist_copy = linklist;
cout << "复制的链表输出:" << endl;
linklist_copy.Reset(0);
while (!linklist_copy.EndOfList()) {
cout << linklist_copy.Data() << endl;
linklist_copy.Next();
}
cout << endl;
//接下来删除第8个元素
linklist.Reset(7);
linklist.DeleteCurrent();
cout << "删除第8个元素后的链表输出:" << endl;
linklist.Reset(0);
while (!linklist.EndOfList()) {
cout << linklist.Data() << endl;
linklist.Next();
}
cout << endl;
system("pause");
return 0;
}
单链表类模板的实现190918
最新推荐文章于 2022-03-23 16:30:48 发布