从C++开始的编程生活(13)——list和浅谈stack、queue

前言

本系列文章承接C语言的学习,需要++有C语言的基础++ 才能学会哦~

第13篇主要讲的是有关于C++的++list++ 和++浅谈stack、queue++ 。
C++才起步,都很简单!!

目录

list

基本用法

push_back()

emplace_back()

[reverse( )](#reverse( ))

[merge( )](#merge( ))

[unique( )](#unique( ))

[remove( )](#remove( ))

[splice( )](#splice( ))

sort()

迭代器分类

list的模拟实现

stack和queue


list

底层结构是带头双向循环链表,也是一种顺序容器

因为是带头双向循环,所以其迭代器++end()指向的是哨兵位++ ,++begin()是哨兵位下一个++。

基本用法

push_back()

cpp 复制代码
list<pos> lt;
pos p1(1,1);
lt.push_back(p1);
lt.push_back(pos(2,2);
lt.push_back({3,3});

push_back的++参数必须是对应的类型++,这里是pos,传入的必须为pos,第三个push_back为隐式类型转换。

emplace_back()

cpp 复制代码
lt.emplace_back(p1);
lt.emplace_back(pos(2, 2));
lt.emplace_back(3, 3);

和push_back用法类似,但是++第三行情况下emplace_back更高效(看编译器怎么优化)++。

reverse( )

反转链表。

merge( )

合并++已经排序的++链表,括号内的链表会变为空。

unique( )

去重,只能对++已经排序的链表++使用。

remove( )

移除,相当于find()再erase(),但是++find不到也不会报错++。

splice( )

接合,取一链表或者该链表的一段或者该链表中的一项,粘贴到另一个链表或者改链表的其他位置中,粘贴源被删除。

sort()

排序,list特有的,vector排序可以调用std库的sort,但是list不能用标准库里的sort。这里涉及了迭代器类别的问题。但是**++list.sort()排序的性能比较低++**,数据少或者排序情况少的时候可以用一下。

迭代器分类

|-------|-----------|--------------------------|
| 分类 | 功能 | 常见于容器 |
| 单向迭代器 | ++ | forward_list,unorder_xxx |
| 双向迭代器 | ++/-- | list |
| 随机迭代器 | ++/--/+/- | string/vector |

不同的容器,其迭代器有所不同,功能也有所不同,如果让函数中的迭代器执行功能之外的操作,就会报错。

三者的根据功能,++具有包含与被包含关系++。

list的模拟实现

cpp 复制代码
#pragma once
#include<assert.h>
#include<iostream>
namespace bit
{
	template<class T>
	struct listNode
	{
		//都是公有public,因为各种操作需要访问这些指针
		T _data;
		listNode<T>* _next;
		listNode<T>* _prev;

		list_node(const T& x = T())
			:_data(x)
			, _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;
		}
		//前置
		Self& operator++()
		{
			_node = _node->_next;
			return *this;
		}

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

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

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

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

	//template<class T>
	//struct list_const_iterator
	//{
	//	typedef list_node<T> Node;
	//	typedef list_const_iterator<T> Self;
	//	Node* _node;

	//	list_const_iterator(Node* node)
	//		:_node(node)
	//	{}

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

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

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

	//	const T& operator->()
	//	{
	//		return &_node->_data;
	//	}

	//	bool operator!=(const Self& s)
	//	{
	//		return _node != s._node;
	//	}
	//};
	//一个用class,一个用struct,是因为一个类既有公有又有私有,我们就用class,反之用struct。
	// 这是一个惯例,不这样做效果也一样
	template<class T>
	class list
	{
		typedef listNode<T> Node;
	public:
		typedef list_iterator<T, T&, T*> iterator;
		typedef const 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 iterator(_head->_next);
		}

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

		~list()
		{
			clear();

			delete _head;
			_head = nullptr;
		}

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

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

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

		list()
		{
			empty_init();
		}

		list(const list<T>& lt)
		{
			empty_init();

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

		list<T>& operator=(list<T> lt)
		{
			swap(lt);
			return *this;
		}

		list(size_t n, cosnt T& val = T())
		{
			empty_init();
			for (size_t i = 0; i < n; i++)
			{
				push_back({ 3,3 });
			}
		}

		void push_back(const T& x)
		{
			//Node* new_node = new Node(x);
			//Node* tail = _head->prex;

			//_tail->_next = new_node;
			//new_node->prec = tail;

			//new_node->_next = _head;
			//_head->_prev = new_node;

			insert(end(), x);
		}

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

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

			prev->_next = newnode;
			newnode->prev = prev;

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

			_size++;

			return iterator(newnode);
		}

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

			prev->_next = next;
			next->_prev = prev;
			delete del;

			--_size;
		}

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

stack和queue

栈和队列,是++容器适配器++(之后会深入讲)。

其成员函数与其他的STL容器都十分类似。++特别的是,这两者没有迭代器++。

❤~~本文完结!!感谢观看!!接下来更精彩!!欢迎来我博客做客~~❤

相关推荐
深思慎考6 小时前
微服务即时通讯系统(服务端)——用户子服务实现逻辑全解析(4)
linux·c++·微服务·云原生·架构·通讯系统·大学生项目
一晌小贪欢6 小时前
【Python数据分析】数据分析与可视化
开发语言·python·数据分析·数据可视化·数据清洗
草莓火锅8 小时前
用c++使输入的数字各个位上数字反转得到一个新数
开发语言·c++·算法
j_xxx404_8 小时前
C++ STL:阅读list源码|list类模拟|优化构造|优化const迭代器|优化迭代器模板|附源码
开发语言·c++
DreamNotOver8 小时前
批量转换论文正文引用为上标
开发语言·论文上标
散峰而望8 小时前
C/C++输入输出初级(一) (算法竞赛)
c语言·开发语言·c++·算法·github
fie88898 小时前
基于MATLAB的狼群算法实现
开发语言·算法·matlab
gihigo19988 小时前
MATLAB中生成混淆矩阵
开发语言·matlab·矩阵
曾几何时`9 小时前
C++——this指针
开发语言·c++