list的使用和模拟实现

发布于:2025-06-30 ⋅ 阅读:(12) ⋅ 点赞:(0)

list 的使用

list 就是带头双向循环链表

要用到的头文件和命名空间

#include <iostream>
#include <list> //带头双向循环链表
#include <vector>
#include <initializer_list>
#include <algorithm>

using namespace std;

构造

void test_list1()
{
	//无参构造
	list<int> lt1;
	//n个val构造
	list<int> lt2(10, 1);
	//迭代器区间构造
	vector<int> v1({1, 2, 3, 4, 5});
	list<int> lt3(lt2.begin(), lt2.end());
	list<int> lt4(v1.begin(), v1.end());
	//迭代器区间构造也可以传指针
	//指针就是一种特殊的迭代器,前提是指针是指向数组的指针
	//迭代器的行为本质模拟的就是指向数组的指针
	int a[] = { 1, 2, 3, 4 };
	list<int> lt5(a, a + 4);

	//initializer_list构造
	list<int> lt6 = { 1, 2, 3, 4, 5 };
	//拷贝构造
	list<int> lt7 = lt2;

	// 1、封装,通用的相似的遍历容器的方式,并且封装屏蔽容器结构的差异和底层实现细节
	// 2、通用/复用,实现算法时用迭代器函数模板方式实现,跟底层容器解耦
	list<int>::iterator it4 = lt4.begin();
	while (it4 != lt4.end())
	{
		cout << *it4 << " ";
		it4++;
	}
	cout << endl;

	for (auto e : lt4)
	{
		cout << e << " ";
	}
	cout << endl;

	//一个算法,不是所有的容器都可以使用,算法对迭代器是有一些要求的,
	//算法迭代器名字就是要求,迭代器有:随机/单项/双向迭代器
	//单项<双向<随机,就是随机迭代器可以适用其他的迭代器的算法
	//因为随机可以看作特殊的双向,双向可以看作特殊的单项
	//例如:sort要求RandomAccessIterator,即容器迭代器是随机迭代器
	//vector就符合要求,但list的迭代器是BidirectionalIterator(双向迭代器),不能使用sort
	sort(a, a + 4);
	sort(v1.begin(), v1.end());
	//sort(lt4.begin(), lt4.end()); //运行报错
}

int main()
{
	test_list1();
	return 0;
}

在这里插入图片描述

void test_list2()
{
	list<int> lt1 = { 1, 2, 3, 4, 5, 6, 7 };
	// 尾插
	lt1.push_back(10);
	// 头插
	lt1.push_front(10);
	for (auto e : lt1)
	{
		cout << e << " ";
	}
	cout << endl;
	
	// 改变lt1中元素个数
	lt1.resize(20, 4);
	for (auto e : lt1)
	{
		cout << e << " ";
	}
	cout << endl;

	lt1.resize(3);
	for (auto e : lt1)
	{
		cout << e << " ";
	}
	cout << endl;

	//因为list不能使用算法库的sort,所以自己实现了一个sort
	//算法库的sort用的快排,list内部实现的sort用的归并排序
	//它们的时间复杂度都是NlogN,但经过测验可知,要排的数据
	//少的时候可以用list内部的,数据量大的话最好用算法库里的
	//可以通过将list中的数据拷贝到vector,再排序,再拷贝回来的方式
}

int main()
{
	test_list2();
	return 0;
}

在这里插入图片描述

测试算法库中的sort和list中的sort的快慢

void test_op1()
{
	srand(time(0));
	const int N = 1000000;

	list<int> lt;
	vector<int> v;

	for (int i = 0; i < N; ++i)
	{
		auto e = rand() + i;
		lt.push_back(e);
		v.push_back(e);
	}

	int begin1 = clock();
	sort(v.begin(), v.end());
	int end1 = clock();

	int begin2 = clock();
	lt.sort();
	int end2 = clock();

	cout << "vector sort:" << end1 - begin1 << endl;
	cout << "list sort:" << end2 - begin2 << endl;

}

int main()
{
	test_op1();
	return 0;
}

在这里插入图片描述

void test_op2()
{
	srand(time(0));
	const int N = 1000000;

	list<int> lt1;
	list<int> lt2;

	for (int i = 0; i < N; ++i)
	{
		auto e = rand() + i;
		lt1.push_back(e);
		lt2.push_back(e);
	}

	int begin1 = clock();
	//拷贝vector
	vector<int> v(lt1.begin(), lt1.end());
	//排序
	sort(v.begin(), v.end());
	//拷贝回lt1
	lt1.assign(v.begin(), v.end());
	int end1 = clock();

	int begin2 = clock();
	lt2.sort();
	int end2 = clock();

	cout << "list copy vector sort copy list sort:" << end1 - begin1 << endl;
	cout << "list sort:" << end2 - begin2 << endl;

}

int main()
{
	test_op2();
	return 0;
}

在这里插入图片描述

void test_list3()
{
	//merge归并排序
	list<double> first, second;

	first.push_back(3.1);
	first.push_back(2.2);
	first.push_back(2.9);

	second.push_back(3.7);
	second.push_back(7.1);
	second.push_back(1.4);

	//归并排序前提:两个list对象都已经有序
	first.sort();
	second.sort();

	//归并后,second的数据全在first,second为空
	first.merge(second);

	cout << "first:";
	for (auto e : first)
	{
		cout << e << " ";
	}
	cout << endl;

	cout << "second:";
	for (auto e : second)
	{
		cout << e << " ";
	}
	cout << endl << endl;

	//unique去掉重复的数据
	list<int> lt1 = { 2, 3, 1, 3, 5, 4, 6, 1, 8, 9, 0, 1, 2 };

	//去重之前要排好序
	lt1.sort();

	lt1.unique();

	for (auto e : lt1)
	{
		cout << e << " ";
	}
	cout << endl << endl;

	//remove删除val这个值,如果这个值有多个,就全删
	list<int> lt2 = { 2, 3, 1, 3, 5, 4, 6, 1, 8, 9, 0, 1, 2 };
	for (auto e : lt2)
	{
		cout << e << " ";
	}
	cout << endl;
	lt2.remove(2);
	for (auto e : lt2)
	{
		cout << e << " ";
	}
	cout << endl << endl;

	//splice转移,将一个迭代器或迭代器区间中的值转移到pos迭代器位置之前
	//可以在同一个对象中转移,也可以在两个不同对象中转移
	list<int> lt3 = { 1, 2, 3, 4, 5, 6 };
	for (auto e : lt3)
	{
		cout << e << " ";
	}
	cout << endl;
	auto it3 = find(lt3.begin(), lt3.end(), 5);
	if (it3 != lt3.end())
	{
		//将5转移到头部位置
		lt3.splice(lt3.begin(), lt3, it3);
	}
	for (auto e : lt3)
	{
		cout << e << " ";
	}
	cout << endl;

	list<int> lt4 = { 7, 8, 9, 10 };
	cout << "转移前lt3:";
	for (auto e : lt3)
	{
		cout << e << " ";
	}
	cout << endl;
	cout << "转移前lt4:";
	for (auto e : lt4)
	{
		cout << e << " ";
	}
	cout << endl;
	//将lt4中的数据转移到lt3的头部位置
	lt3.splice(lt3.begin(), lt4, lt4.begin(), lt4.end());
	cout << "转移后lt3:";
	for (auto e : lt3)
	{
		cout << e << " ";
	}
	cout << endl;
	cout << "转移后lt4:";
	for (auto e : lt4)
	{
		cout << e << " ";
	}
	cout << endl;
}

int main()
{
	test_list3();
	return 0;
}

在这里插入图片描述

list 的模拟实现

list.h

#pragma once

namespace bs
{
	//节点
	template<class T>
	struct list_node
	{
		T _data;
		list_node<T>* _next;
		list_node<T>* _prev;

		list_node(const T& val = T())
			:_data(val)
			,_next(nullptr)
			,_prev(nullptr)
		{}
	};

	//迭代器
	template<class T, class Ref, class Ptr>
	struct __list_iterator
	{
		typedef list_node<T> Node;
		typedef __list_iterator<T, Ref, Ptr> Self;
		Node* _node;

		__list_iterator(Node* node)
			:_node(node)
		{}

		Ref operator*()
		{
			return _node->_data;
		}

		Ptr operator->()
		{
			return &_node->_data;
		}

		//前置++
		Self& operator++()
		{
			_node = _node->_next;
			return *this;
		}

		//后置++
		Self operator++(int)
		{
			Self tmp(*this);
			_node = _node->_next;
			return tmp;
		}

		//前置--
		Self& operator--()
		{
			_node = _node->_prev;
			return *this;
		}

		//后置--
		Self operator--(int)
		{
			Self tmp(*this);
			_node = _node->_prev;
			return tmp;
		}

		bool operator!=(const Self& it) const
		{
			return _node != it._node;
		}

		bool operator==(const Self& it) const
		{
			return _node == it._node;
		}
	};

	//链表
	template<class T>
	class list
	{
		typedef list_node<T> Node;
	public:

		typedef __list_iterator<T, T&, T*> iterator;
		typedef __list_iterator<T, const T&, const T*> const_iterator;

		iterator begin()
		{
			return iterator(_head->_next);
		}

		iterator end()
		{
			return iterator(_head);
		}

		const_iterator begin() const
		{
			return const_iterator(_head->_next);
		}

		const_iterator end() const
		{
			return const_iterator(_head);
		}

		void empty_init()
		{
			_head = new Node;
			_head->_next = _head;
			_head->_prev = _head;
		}

		list()
		{
			empty_init();
		}

		//lt2(lt1)
		//list(const list<T>& lt)
		list(const list& lt) //在类里面可以不加模板参数
		{
			empty_init();

			for (const auto& e : lt)
			{
				push_back(e);
			}
		}

		list(initializer_list<T> il)
		{
			empty_init();

			for (const auto& e : il)
			{
				push_back(e);
			}
		}

		void swap(list<T>& lt)
		{
			std::swap(_head, lt._head);
			std::swap(_size, lt._size);
		}

		//lt1 = lt3
		list<T>& operator=(list<T> lt)
		{
			swap(lt);

			return *this;
		}

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

		//	return *this;
		//}

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

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

		void push_back(const T& x)
		{
			insert(end(), x);
		}

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

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

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

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

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

			++_size;

			//返回新插入节点位置的迭代器
			return iterator(newnode);
		}

		iterator erase(iterator pos)
		{
			Node* cur = pos._node;
			Node* prev = cur->_prev;
			Node* next = cur->_next;

			//prev cur next
			prev->_next = next;
			next->_prev = prev;

			delete cur;

			--_size;

			//返回下一个位置的迭代器
			//return iterator(next);
			return next; //单参数构造函数的隐式类型转换
		}

		size_t size()
		{
			//size_t n = 0;
			//for (auto& e : *this)
			//{
			//	++n;
			//}
			//return n;

			return _size;
		}

	private:
		Node* _head;
		size_t _size = 0;
	};

}

test.cpp

#include "list.h"

namespace bs
{
	template<class T>
	void Print(const bs::list<T>& lt)
	{
		//类模板未实例化,不能去类模板中找后面的东西
		//编译器就分不清const_iterator是嵌套类型还是静态成员变量
		//typename告诉编译器,我确认过了这里是类型
		//typename list<T>::const_iterator it = lt.begin();
		auto it = lt.begin();
		while (it != lt.end())
		{
			//it += 1; //const迭代器,指向内容不能修改

			cout << *it << " ";
			++it;
		}
		cout << endl;
	}
	
	void test_list1()
	{
		bs::list<int> lt1;
		lt1.push_back(1);
		lt1.push_back(2);
		lt1.push_back(3);
		lt1.push_back(4);
		bs::list<int>::iterator it1 = lt1.begin();
		while (it1 != lt1.end())
		{
			cout << *it1 << " ";
			++it1;
		}
		cout << endl;
	}

	void test_list2()
	{
		bs::list<int> lt1;
		lt1.push_back(1);
		lt1.push_back(2);
		lt1.push_back(3);
		lt1.push_back(4);
		bs::list<int>::iterator it1 = lt1.begin();
		while (it1 != lt1.end())
		{
			*it1 += 1; //迭代器,指向内容可以修改

			cout << *it1 << " ";
			++it1;
		}
		cout << endl;

		Print(lt1);
	}

	struct Pos
	{
		int _row;
		int _col;

		Pos(int row = 0, int col = 0)
			:_row(row)
			,_col(col)
		{}
	};

	void test_list3()
	{
		bs::list<Pos> lt1;
		lt1.push_back({ 1, 1 });
		lt1.push_back({ 2, 2 });
		lt1.push_back({ 3, 3 });
		lt1.push_back({ 4, 4 });

		//bs::list<Pos>::iterator it1 = lt1.begin();
		auto it1 = lt1.begin();
		while (it1 != lt1.end())
		{
			//cout << (*it1)._row << ":" << (*it1)._col << endl;
			//为了可读性,这里省略了一个->
			//cout << it1->_row << ":" << it1->_col << endl;
			cout << it1.operator->()->_row << ":" << it1.operator->()->_col << endl;

			++it1;
		}
		cout << endl;

	}

	void test_list4()
	{
		bs::list<int> lt1;
		lt1.push_back(1);
		lt1.push_back(2);
		lt1.push_back(3);
		lt1.push_back(4);
		Print(lt1);
		lt1.push_front(10);
		lt1.push_front(20);
		Print(lt1);
		lt1.pop_front();
		lt1.pop_front();
		Print(lt1);
		lt1.pop_back();
		lt1.pop_back();
		Print(lt1);
	}

	void test_list5()
	{
		bs::list<int> lt1;
		lt1.push_back(1);
		lt1.push_back(2);
		lt1.push_back(3);
		lt1.push_back(4);
		Print(lt1);
		bs::list<int> lt2 = lt1;
		Print(lt2);
		bs::list<int> lt3 = { 10, 20, 30 };
		lt1 = lt3;
		Print(lt1);

	}

	void test_list6()
	{
		bs::list<int> lt1 = { 10, 20, 30 };
		Print(lt1);

		bs::list<double> lt2 = { 10.1, 20.1, 30.1 };
		Print(lt2);

	}
}

int main()
{
	bs::test_list6();
	//test_op2();
	return 0;
}

网站公告

今日签到

点亮在社区的每一天
去签到