C++实现链表类

本文给出C++ STL中list的主要函数模拟实现

在给出代码之前 , 我想作以下几点说明 :

1 . 本代码只是模拟list的实现 , 由于我本人才疏学浅 , 代码实现可能与STL版本大相径庭

2 . STL中的迭代器是用模板类实现 , 本代码只是用一个类指针来模拟 , 因此使用较为繁琐

3 . 本代码的函数版本较为简易 , 几乎不支持任何泛型算法

//头文件 mylist.h
#pragma once
#include<iostream>
using namespace std;
template <typename t> class Node
{
public:
	t data;
	Node* next;
	Node* prev ;
};
template <typename T> class mylist:public Node<T>
{
public:
	void construct();					//构造list
	mylist();							//空list
	mylist(int size_of_list);			//指定大小的list
	mylist(initializer_list<T>ls);		//初始化列表
	mylist(int size_of_list, T val);	//指定大小的list和所有初始元素
	mylist(mylist& A);					//拷贝构造函数
	void push_back(T val);				//尾插
	void push_front(T val);				//头插
	void pop_back();					//尾弹
	void pop_front();					//首弹
	bool empty();						//判断list是否为空
	void resize(int n);					//调用resize(n)将list的长度改为只容纳n个元素,超出的元素将被删除。如果n比list原来的长度长,那么默认超出的部分元素置为0。
	void clear();						//清空所有元素
	void remove(T data);				//删除具有特定值的元素
	void reverse();						//反转list(迭代法)
	void assign(int n, T val);			//将list中的n个元素替换为val
	mylist<T>& assign(Node<T> *A, Node<T> *B);//将一定范围内的元素替换到list
	void merge(mylist<T> &A);			//将另一个list合并于本list中
	Node<T>* erase(Node<T>* it);				//删除某个元素
	Node<T>* erase(Node<T>* lhs, Node<T>* rhs);	//删除某个范围内的元素
	Node<T>* insert(Node<T>* it, T val);		//在某个位置插入一个元素
	Node<T>* insert(Node<T>* it, int n, T val); //某个位置插入n个元素
	T operator[](int n);				//重载[] 用于便捷访问list中的元素
	T operator*();						//重载* 用于解引用list的迭代器
	mylist<T> &operator++();			//前置递增
	mylist<T> &operator++(int);			//后置递增		
	mylist<T> &operator--();			//前置递减
	mylist<T> &operator--(int);			//后置递减
	mylist<T> &operator+=(int step);	//复合赋值运算符
	mylist<T> &operator-=(int step);	//复合赋值运算符
	void operator=(Node<T>* it);		//重载= 用来简化迭代器
	Node<T>* iterator;					//模拟迭代器
	Node<T>* begin();					//首迭代器,list第一个元素的位置
	Node<T>* end();						//尾迭代器,list最后一个元素之后一个位置
	Node<T>* rbegin();					//反向首迭代器
	Node<T>* rend();					//反向尾迭代器
	int size();							//获取list大小的接口
	T& back();							//返回第一个元素的值
	T& front();							//返回最后一个元素的值
	void display();						//用箭头显示该链表所有元素

private:
	int renew_len();					//获取当前list的大小
	int len;							//list的大小
	Node<T>* head;						//list的头结点(头结点数据域为空)
	Node<T>* tail;						//list的尾结点(尾结点是list的最后一个结点)
};
template <class T>void mylist<T>::construct()
{
	head = new Node<T>;
	head->prev = nullptr;
	head->next = nullptr;
	iterator = head;
	len = 0;
}
template <class T>mylist<T>::mylist()
{
	this->construct();
}
template <class T>mylist<T>::mylist(int size_of_list)
{
	this->construct();
	for (int i = 0; i < size_of_list; ++i)
	{
		this->push_back(0);
	}
}
template<class T>mylist<T>::mylist(initializer_list<T>ls)
{
	this->construct();
	for (auto& x : ls)
	{
		this->push_back(x);
	}
}
template<class T>mylist<T>::mylist(int size_of_list, T val)
{
	this->construct();
	for (int i = 0; i < size_of_list; ++i)
	{
		this->push_back(val);
	}
}
template<class T>mylist<T>::mylist(mylist& A)
{
	this->construct();
	this->assign(A.begin(), A.tail);
}
template <class T> void mylist<T>::push_back(T val)
{
	if (head->next == nullptr)
	{
		tail = head;
	}
	Node<T>* tmp = new Node<T>;
	tmp->data = val;
	tmp->prev = tail;
	tail->next = tmp;
	tail = tmp;
	tail->next = nullptr;
	++len;
}
template <class T> void mylist<T>::push_front(T val)
{
	if (head->next == nullptr)
	{
		this->push_back(val);
	}
	else
	{
		Node<T>* tmp = new Node<T>;
		tmp->data = val;
		tmp->next = head->next;
		tmp->prev = head->next->prev;
		head->next->prev = tmp;
		head->next = tmp;
	}
	++len;
}
template <class T> bool mylist<T>::empty()
{
	return size() ? true : false;
}
template <class T>void mylist<T>::resize(int n)
{
	Node<T>* p = head;
	int size = len;
	if (n == size)
	{
		return;
	}
	else if (n < size)
	{
		for (int i = 0; i < n; ++i)
		{
			p = p->next;
		}
		p = p->next;
		Node<T>* tmp = p;
		bool flag = true;
		while (flag)
		{
			if (p == tail)
			{
				flag = false;
			}
			p = erase(p);
		}
	}
	else if (n > size)
	{
		for (int i = 0; i < n - size; ++i)
		{
			push_back(0);
		}
	}
	renew_len();
}
template <class T> void mylist<T>::clear()
{
	Node<T>* p = head;
	Node<T>* tmp;
	for (int i = 0; i < len; ++i)
	{
		tmp = p->next;
		delete p;
		p = tmp;
	}
	head->next = nullptr;
	renew_len();
}
template <class T> Node<T>* mylist<T>::erase(Node<T>* it)
{
	if (it ->next==nullptr)
	{
		tail = tail->prev;
		it->prev->next = nullptr;
		delete it;
		renew_len();
		return tail->next;
	}
	else
	{
		Node<T>* tmp = it->next;
		it->prev->next = it->next;
		it->next->prev = it->prev;
		delete it;
		renew_len();
		return tmp;
	}

}
template <class T> Node<T>* mylist<T>::erase(Node<T>* lhs, Node<T>* rhs)
{
	Node<T>* p = lhs;
	bool flag = true;
	while (flag)
	{
		if (p == rhs)
		{
			flag = false;
		}
		else
		{
			p = erase(p);
		}
	}
	if (rhs->next==nullptr)
	{
		tail = lhs->prev;
	}
	renew_len();
	return p;
}
template <class T> int mylist<T>::renew_len()
{
	int j = 0;
	if (head->next == nullptr)
	{
		this->len = j;
		return j;
	}
	Node<T>* tmp = head;
	while (tmp ->next!=nullptr)
	{
		tmp = tmp->next;
		++j;
	}
	this->len = j;
	return j;
}
template <class T> int mylist<T>::size()
{
	try
	{
		if (len < 0)
		{
			throw runtime_error("The size of list cannot less than 0");
		}
		return len;
	}
	catch (runtime_error& err)
	{
		cout << err.what();
	}
}
template <class T>T& mylist<T>::back()
{
	return tail->data;
}
template<class T>T& mylist<T>::front()
{
	return head->next->data;
}
template<class T> Node<T>* mylist<T>::begin()
{
	return head->next;
}
template<class T>Node<T>* mylist<T>::end()
{
	return tail->next;
}
template<class T> Node<T>* mylist<T>::rend()
{
	return head;
}
template<class T>Node<T>* mylist<T>::rbegin()
{
	return tail;
}
template<class T>T mylist<T>::operator[](int n)
{
	try
	{
		if (len == 0)
		{
			throw(runtime_error("error:The list is empty! "));
		}
	}
	catch (runtime_error& err)
	{
		cout << err.what();
	}
	Node<T>* p = head->next;
	for (int i = 0; i < n; ++i)
	{
		p = p->next;
	}
	return p->data;
}
template<class T>T mylist<T>::operator*()
{
	try
	{
		if (head->next == nullptr)
		{
			throw runtime_error("The list is empty!");
		}
		else
		{
			return iterator->data;
		}
	}
	catch (runtime_error& err)
	{
		cout << err.what() << endl;
	}
}
template<class T>mylist<T>& mylist<T>::operator++()
{
	this->iterator = this->iterator->next;
	return *this;
}
template<class T>mylist<T>&mylist<T>::operator--()
{
	if (iterator == end())
	{
		iterator = tail;
		return *this;
	}
	iterator = iterator->prev;
	return *this;
}
template<class T>mylist<T>& mylist<T>::operator++(int)
{
	mylist<T>tmp = *this;
	iterator = iterator->next;
	return tmp;
}
template<class T>mylist<T> &mylist<T>::operator--(int)
{
	if (iterator == end())
	{
		iterator = tail;
		return *this;
	}
	mylist<T>tmp = *this;
	iterator = iterator->prev;
	return tmp;
}
template<class T>mylist<T> &mylist<T>::operator+=(int step)
{
	for (int i = 0; i < step; ++i)
	{
		++* this;
	}
	return *this;
}
template<class T>mylist<T> &mylist<T>::operator-=(int step)
{
	for (int i = 0; i < step; ++i)
	{
		--* this;
	}
	return *this;
}
template<class T>void mylist<T>::operator=(Node<T>* it)
{
	this->iterator = it;
}
template<class T>void mylist<T>::remove(T data)
{
	if (len == 0)
	{
		cout << "The list is empty" << endl;
		return;
	}
	Node<T>* p = head;
	while (1)
	{
		p = p->next;
		if (p != tail)
		{
			if (p->data == data)
			{
				p = erase(p);
				--* this;
			}
		}
		if (p == tail)
		{
			break;
		}
	}
}
template<class T>void mylist<T>::display()
{
	if (len == 0)
	{
		cout << "The list is empty" << endl;
		return;
	}
	Node<T>* p = head;
	while (1)
	{
		p = p->next;
		cout << p->data;
		if (p ->next!= nullptr)
		{
			cout << "-->";
		}
		if (p ->next == nullptr)
		{
			break;
		}
	}
	cout << endl;
}
template<class T>Node<T>* mylist<T>::insert(Node<T>* it, T val)
{
	Node<T>* tmp = new Node<T>;
	tmp->data = val;
	it->prev->next = tmp;
	tmp->next = it;
	tmp->prev = it->prev;
	it->prev = tmp;
	renew_len();
	return tmp;
}
template<class T>Node<T>* mylist<T>::insert(Node<T>* it, int n, T val)
{
	Node<T>* tmp = it;
	for (int i = 0; i < n; ++i)
	{
		tmp = insert(tmp, val);
	}
	renew_len();
	return tmp;
}
template <class T>void mylist<T>::reverse()
{
	Node<T>* p = head->next;
	Node<T>* newtail = head->next;
	while (p != nullptr)
	{
		Node<T>* p_next = p->next;
		p->next = p->prev;
		p->prev = p_next;
		p = p_next;
	}
	head->next = tail;
	tail->prev = head;
	tail = newtail;
	tail->next = nullptr;
}
template <class T>void mylist<T>::pop_back()
{
	this->erase(tail);
}
template <class T>void mylist<T>::pop_front()
{
	this->erase(head->next);
}
template <class T>void mylist<T>::assign(int n, T val)
{
	this->resize(n);
	Node<T>* p = head;
	while (1)
	{
		p = p->next;
		p->data = val;
		if (p == tail)
		{
			break;
		}
	}
}
template <class T>mylist<T>& mylist<T>::assign(Node<T>* A, Node<T> *B)
{
	bool flag = true;
	Node<T>* p1 = head;
	Node<T>* p2 = A;
	int cnt = 0;
	while (flag)
	{
		if (p2 == B)
		{
			flag = false;
		}
		p2 = p2->next;							
		cnt++;
	}
	int safe_len;
	if (cnt >= len)
	{
		safe_len = cnt;
	}
	else
	{
		safe_len = len;
	}
	this->resize(safe_len);
	flag = true;
	p2 = A;
	while (flag)
	{
		if (p2 == B)
		{
			flag = false;
		}
		p1 = p1->next;
		p1->data = p2->data;
		p2 = p2->next;
	}
	return *this;
}
template <class T>void mylist<T>::merge(mylist &A)
{
	tail->next = A.head->next;	
	tail = A.tail;
	A.head->next = nullptr;
	A.renew_len();
	renew_len();
}

下面我们来对代码进行测试 :

//测试代码
#include"mylist.h"
#include<string>
int main()
{
	mylist<int>L1;
	mylist<char>L2{ 'A','B','C'};
	mylist<string>L3{ "you","and","me" };
	mylist<double>L4(5, 3.14);
	
	L2.display();
	L3.display();
	L4.display();

	for (int i = 1; i <= 10; i++)
	{
		L1.push_back(i);
	}

	mylist<int>L5(L1);				//以L1来构造L5

	for (L1.iterator = L1.begin(); L1.iterator != L1.end(); ++L1)
	{
		cout << *L1 << " ";			//遍历并输出L1中的所有元素
	}
	for (int i = 1; i <= 10; i++)
	{
		L1.push_front(i);			//头插法向L1插入元素
	}
	cout << endl;
	L1.display();
	L1.remove(9);					//删除L1中值为9的元素
	L1.push_back(100);				//尾插100
	L1.pop_front();					//首弹
	L1.display();
	cout << L1.size() << endl;		//输出L1的大小
	L1.iterator = L1.begin();		//建立L1的模拟迭代器
	L1 += 5;
	L1.erase(L1.iterator);
	L1.display();
	L1.iterator = L1.end();
	L1 -= 2;
	auto it2 = L1.iterator;
	L1.iterator = L1.begin();
	L1 += 10;
	auto it1 = L1.iterator;
	L1.erase(it1, it2);			//it1指向L1的第11个元素,it2指向L1的倒数第二个元素
	L1.display();
	mylist<int>L6{ 1,2,3 };	
	L1.iterator = L1.begin();
	it1 = L1.iterator;
	L1 += 5;
	it2 = L1.iterator;
	cout << endl;
	L6.assign(it1, it2);		//it1指向L1的第1个元素,it2指向L1的第6个元素,把L1的第1个元素到第6个元素分配给L6
	cout << endl;
	L6.display();
	L1.display();
	L1.reverse();				//反转L1			
	L1.display();
	L1.merge(L5);				//将L1和L5合并于L1
	L1.display();
	cout << L1.back()<< endl;   //输出L1的最后一个元素
	L1.clear();					//清空L1
	cout << L1.empty();			//判断L1是否为空
	cout << endl << endl;

	cout << L2[1] << endl;		//输出L2的第2个元素
	L2.push_front('E');			//L2首插E
	L2.display();
	cout << endl;

	L3.push_back("love");		//L3尾插love
	L3.remove("and");			//L3去除and
	L3.display();
	cout << endl;

	L4.resize(2);				//将L4大小设置为2
	L4.display();
	L4.resize(5);				//将L4大小设置为5
	L4.display();
	L4.pop_back();				//尾弹L4
	L4.display();
	L4.pop_front();				//首弹L4
	L4.display();
	L4.insert(L4.begin(), 999);	//在L4首部插入999
	L4.iterator = L4.begin();	
	L4 += 3;
	L4.insert(L4.iterator, 3, 777);	//在L4的第4个元素位置插入3个777
	L4.display();
	cout << L4.size() << endl;	//输出L4大小
	L4.assign(7, 333);			//将7个333分配给L4
	L4.display();
}

最终呈现效果如下 :
在这里插入图片描述
代码水平不高 , 恳请大家批评指正 !

  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值