单链表类模板的实现190918

#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;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值