C++从零开始(day33)——list模拟实现3

这是关于一个普通双非本科大一学生的C++的学习记录贴

在此前,我学了一点点C语言还有简单的数据结构,如果有小伙伴想和我一起学习的,可以私信我交流分享学习资料

那么开启正题

今天分享的是关于list的模拟实现,今天收尾,明天开始stack和queue

1.insert函数

void insert(iterator pos, const T& x)
{
	Node* cur = pos._node;
	Node* prev = cur->_prev;
	Node* newnode = new Node(x);

	newnode->_next = cur;
	newnode->_prev = prev;
	prev->_next = newnode;
	cur->_prev = newnode;
}

实现insert函数后,再实现push_back(),push_front(),直接复用即可

void push_front(const T& x)
{
	insert(begin(), x);
}

void push_back(const T& x)
{
	insert(end(),x);
	/*Node* tail = _head->_prev;
	Node* newnode = new Node(x);

	newnode->_next = _head;
	newnode->_prev = tail;
	tail->_next = newnode;
	_head->_prev = newnode;*/
}

2.erase函数

void erase(iterator pos)
{
	assert(pos != end());
	Node* prev = pos._node->_prev;
	Node* next = pos._node->_next;

	delete pos._node;

	prev->_next = next;
	next->_prev = prev;
}

erase函数实现时要注意释放空间,否则会导致内存泄漏

同样的,pop_back(),pop_front(),都复用实现

void pop_back()
{
	erase(--end());
}

void pop_front()
{
	erase(begin());
}

3.clear函数与析构函数

实现erase函数后clear与析构函数复用实现就很便捷快速了

~list()
{
	clear();
	delete[] _head;
	_head = nullptr;
}

void clear()
{
	iterator it = begin();
	while (it != end())
	{
		erase(it++);
	}
}

注意这里的erase(it++)不能分开写,会导师迭代器失效

4.拷贝构造函数

list(const list<T>& l)
{
	_head = new Node;
	_head->_next = _head;
	_head->_prev = _head;

	/*const_iterator it = l.begin();
	while (it != l.end())
	{
		push_back(*it);
		++it;
	}*/

	for (auto e : l)
	{
		push_back(e);
	}
}

由于涉及到内存管理,拷贝构造函数必须是深拷贝,这里我们用了两种写法,一种是迭代器,一种是范围for

5.赋值运算符重载

list<T>& operator=(const list<T>& l)
{
	if (this != &l)
	{
		clear();
		for (auto e : l)
			push_back(e);
	}

	return *this;
}

上面是一般写法,当然也有现代写法,如下

list<T>& operator=(list<T> l)
{
	/*if (this != &l)
	{
		clear();
		for (auto e : l)
			push_back(e);
	}

	return *this;*/

	swap(_head, l._head);

	return *this;
}

相比之下,现代写法要简洁得多

6.迭代器失效

list的insert不会使迭代器失效,而erase会,迭代器失效的本质是迭代器空间被释放无法访问,所以vector的某些函数造成迭代器失效与list并无太大关联

7.比较vector与list

vector是一个可动态增长的数组

优点:随机访问,很好的支持了排序,二分查找,堆算法等

缺点:头部或中间的插入删除效率低,空间不够增容代价大

lsit是一个带头双向循环的链表

优点:任意位置插入删除数据效率高

缺点:不支持随机访问

总结:vector和list是两个相辅相成,互补的容器

新手写博客,有不对的位置希望大佬们能够指出,也谢谢大家能看到这里,让我们一起学习进步吧!! 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值