从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容器都十分类似。++特别的是,这两者没有迭代器++。

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

相关推荐
AA陈超20 小时前
Lyra学习004:GameFeatureData分析
c++·笔记·学习·ue5·虚幻引擎
小白学大数据20 小时前
基于Splash的搜狗图片动态页面渲染爬取实战指南
开发语言·爬虫·python
xlq2232220 小时前
22.多态(下)
开发语言·c++·算法
未来之窗软件服务21 小时前
操作系统应用(三十三)php版本选择系统—东方仙盟筑基期
开发语言·php·仙盟创梦ide·东方仙盟·服务器推荐
是Dream呀21 小时前
昇腾实战|算子模板库Catlass与CANN生态适配
开发语言·人工智能·python·华为
零匠学堂202521 小时前
移动学习系统,如何提升企业培训效果?
java·开发语言·spring boot·学习·音视频
不会c嘎嘎21 小时前
【数据结构】AVL树详解:从原理到C++实现
数据结构·c++
小杨快跑~21 小时前
从装饰者到桥接再到工厂:模式组合的艺术
java·开发语言·设计模式
say_fall21 小时前
C语言编程实战:每日一题:随机链表的复制
c语言·开发语言·链表
拾贰_C21 小时前
【Python | Anaconda】 python-Anaconda 一些命令使用
开发语言·python