list容器

底层:

        双向链表



特点:
    1、可在任意位置插入删除元素,不支持随机访问,在插入、删除元素后,原来的迭代器可能会失效
    2、由于链表是通过指针连接的,所以每个元素都需要额外的开销
    3、存储的元素位置不连续,遍历方面效率会低于vector



和vector的区别:
    1、数据存储结构不同:vecotr采用连续的动态数组,list采用双向链表,内存不连续
    2、vector在插入和删除某个元素时,需要移动该元素后的所有元素位置,最坏情况下时间复杂度为o(n);list只需要调整相邻元素的指针即可,时间复杂度为o(1)
    3、vector支持随机访问,list不支持随机访问
    4、vector在创建的时候会预设一段空间,内存不足时会重新分配一片空间,并复制原来的元素到新的内存中;list不需要,只会在插入元素时动态分配内存



成员方法:
    1、构造和析构函数
        explicit list(const Allocator& = Allocator());
        explicit list(size_type count, const T& value = T(),const Allocator& = Allocator());
        template <class InputIt>
        list(InputIt first, InputIt last, const Allocator& = Allocator());
    2、迭代器
        iterator begin() noexcept;
        const_iterator begin() const noexcept;
        iterator end() noexcept;
        const_iterator end() const noexcept;
        reverse_iterator rbegin() noexcept;
        const_reverse_iterator rbegin() const noexcept;
        reverse_iterator rend() noexcept;
        const_reverse_iterator rend() const noexcept;
    3、容量和大小
        bool empty() const noexcept;
        size_type size() const noexcept;
        size_type max_size() const noexcept;
    4、插入和删除
        void clear() noexcept;
        iterator insert(const_iterator pos, const T& value);
        iterator insert(const_iterator pos, T&& value);
        iterator insert(const_iterator pos, size_type count, const T& value);
        template <class InputIt>
        iterator insert(const_iterator pos, InputIt first, InputIt last);
        iterator insert(const_iterator pos, std::initializer_list<T> ilist);
        iterator erase(const_iterator pos);
        iterator erase(const_iterator first, const_iterator last);
        void push_front(const T& value);
        void push_front(T&& value);
        void pop_front();
        void push_back(const T& value);
        void push_back(T&& value);
        void pop_back();
        void resize(size_type count);
        void resize(size_type count, const value_type& value);
        void swap(list& other) noexcept(std::allocator_traits<Allocator>::is_always_equal::value);
    5、访问
        reference front();
        const_reference front() const;
        reference back();
        const_reference back() const;
    6、移动
        list(list&& other) noexcept; 
        list& operator=(list&& other) noexcept;
        void swap(list& other) noexcept(std::allocator_traits<Allocator>::is_always_equal::value);
    7、其他
        void remove(const T& value);
        template<class Predicate>
        void remove_if(Predicate pred);
        void unique();
        template<class BinaryPredicate>
        void unique(BinaryPredicate binary_pred);
        void sort();
        template<class Compare>
        void sort(Compare comp);
        void reverse() noexcept;


成员方法使用示例:

#include<iostream>
#include<list>
int main()
{
//1、构造
	//创建空列表
	std::list<int> listDemo;
	//创建大小为10,且所有元素为5的列表
	std::list<int> listDemo(10, 5);
	std::list<int> listDemo = {1, 2, 3, 4, 5};
	//通过迭代器创建列表
	int arr[5] = { 1, 2, 3, 4, 5 };
	std::list<int> listDemo(arr, arr + 5);

//2、迭代器
	//正向迭代器
	for (std::list<int>::iterator it = listDemo.begin(); it != listDemo.end(); it++) {
		std::cout << *it << " ";
	}
	//反向迭代器
	for (std::list<int>::reverse_iterator rit = listDemo.rbegin(); rit != listDemo.rend(); rit++) {
		std::cout << *rit << " ";
	}
	//常量迭代器
	for (std::list<int>::const_iterator cit = listDemo.begin(); cit != listDemo.end(); cit++) {
		std::cout << *cit << " ";
	}
	//常量反向迭代器
	for (std::list<int>::const_reverse_iterator crit = listDemo.rbegin(); crit != listDemo.rend(); crit++) {
		std::cout << *crit << " ";
	}

//3、容量和大小
	//判断是否为空
	if (listDemo.empty()) {
		std::cout << "listDemo is empty!" << std::endl;
	}
	else {
		std::cout << "listDemo size:" << listDemo.size() << std::endl;
	}

//4、插入和删除
	//---clear---//
	listDemo.clear();

	//---insert---//
	std::list<int>::iterator it = listDemo.begin();
	//当前迭代器it为正向迭代器,向前移动两位,表示第三位,第三位插入6
	std::advance(it, 2); 
	listDemo.insert(it, 6);
	//第3位插入3个7
	std::list<int>::iterator it = listDemo.begin();
	std::advance(it, 2);
	listDemo.insert(it, 3, 7);
	//第三位插入另一个列表中的元素
	std::list<int> _listDemo = {8, 9, 10};
	it = listDemo.end();
	//向后移动1位
	std::advance(it, -1);
	listDemo.insert(it, _listDemo.begin(), _listDemo.end());
	//第1位插入列表多个元素
	listDemo.insert(listDemo.begin(), {11, 12, 13, 14, 15});
	
	//---erase---//
	std::list<int>::iterator it = listDemo.begin();
	//删除第1个元素
	std::advance(it, 0);
	listDemo.erase(it);
	//删除第2个后面的所有元素
	it = listDemo.begin();
	std::advance(it, 2);
	listDemo.erase(it, listDemo.end());
	//删除第2个到第四个元素
	auto it_start = std::next(listDemo.begin(), 1);
	auto it_end = std::next(listDemo.begin(), 3);
	listDemo.erase(it_start, it_end);

	//---push_front && pop_front---//
	//头部插入0
	listDemo.push_front(0);
	//删除第一个元素
	listDemo.pop_front();

	//---resize---//调整列表的大小,如果新的大小小于当前列表,则删除多余元素;如果大于当前大小,则添加默认构造值或指定值
	listDemo.resize(10);
	//使用指定值填充
	listDemo.resize(10, 2);

//5、访问
	//访问第一个和最后一个元素
	int& first = listDemo.front();
	const int& back = listDemo.back();
	first = 12;
	//back = 7 这里编译会报错,因为只能访问不能修改,如果要修改建议写为 int& back = listDemo.back(); 

//6、移动
	std::list<int> list_1 = {1, 2, 3};
	std::list<int> list_2 = {4, 5, 6};
	//移动构造
	std::list<int> list_3(std::move(list_1));
	//移动赋值
	list_2 = std::move(list_3);
	//swap
	list_1.swap(list_2);
	
//7、其他
	std::list<int> list_demo = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
	//remove -> 删除指定元素
	//删除元素2
	list_demo.remove(2);
	//remove_if -> 从列表中删除满足给定条件的所有元素
	//删除偶数
	list_demo.remove_if([](int n) {return n % 2 == 0; });
	//unique -> 移除重复元素
	list_demo.unique();
	//sort -> 排序
	//降序排序 
	list_demo.sort(std::greater<int>());
	//reverse -> 列表中的元素逆序排列
	list_demo.reverse();
	return 0;
}

list类部分方法自定义示例

template<typename T>
class MyList {
private:
	struct Node {
		T data;
		Node* prev;
		Node* next;

		Node(const T& d = T{}, Node* p = nullptr, Node* n = nullptr)
			: data(d), prev(p), next(n) {}
	};

	int size_;
	Node* head_;
	Node* tail_;

public:
	// 构造函数和析构函数
	MyList() : size_(0), head_(new Node()), tail_(new Node()) {
		head_->next = tail_;
		tail_->prev = head_;
	}

	~MyList() {
		clear();
		delete head_;
		delete tail_;
	}

	// 添加元素
	void push_front(const T& val) {
		insert(begin(), val);
	}

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

	// 删除元素
	void pop_front() {
		erase(begin());
	}

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

	void clear() {
		while (!empty()) {
			pop_front();
		}
	}

	// 获取迭代器
	class iterator {
	public:
		iterator() : node_(nullptr) {}

		iterator(Node* n) : node_(n) {}

		iterator& operator++() {
			node_ = node_->next;
			return *this;
		}

		iterator& operator--() {
			node_ = node_->prev;
			return *this;
		}

		bool operator==(const iterator& rhs) const {
			return node_ == rhs.node_;
		}

		bool operator!=(const iterator& rhs) const {
			return !(*this == rhs);
		}

		T& operator*() const {
			return node_->data;
		}

	private:
		Node* node_;
		friend class MyList<T>;
	};

	iterator begin() {
		return iterator(head_->next);
	}

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

	// 访问元素
	T& front() {
		return *begin();
	}

	T& back() {
		return *(--end());
	}

	// 判断容器是否为空
	bool empty() const {
		return size_ == 0;
	}

	// 获取容器大小
	int size() const {
		return size_;
	}

	// 插入元素
	iterator insert(iterator pos, const T& val) {
		Node* prev_node = pos.node_->prev;
		Node* new_node = new Node(val, prev_node, pos.node_);
		prev_node->next = new_node;
		pos.node_->prev = new_node;
		++size_;
		return iterator(new_node);
	}

	// 删除元素
	iterator erase(iterator pos) {
		Node* prev_node = pos.node_->prev;
		Node* next_node = pos.node_->next;
		prev_node->next = next_node;
		next_node->prev = prev_node;
		iterator it(next_node);
		delete pos.node_;
		--size_;
		return it;
	}
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值