【CPP_STL篇】总结可遍历STL所有容器的迭代器(反向迭代器的模拟+实现)

--------------------------------------------------------------------------------------------------------------------------------

每日鸡汤:火车就是这样离我们很近,又离我们很远,中间像是留有期待,留有着人生注定需要的某种时间。

--------------------------------------------------------------------------------------------------------------------------------

一:STL_迭代器

我们知道STL共有六大组件:

我们已经了解了几个容器和配接器的用法,其中容器就是为了存储数据的,分为数组型,链表型,树形......。

那么存储完数据,是不是就应该访问数据了呢?使得,STL中可使用迭代器访问任意容器的数据。

迭代器:封装封闭底层实现的复杂细节,用统一简单的方式来访问容器。

我们以前在模拟的时候就发现了,string 和 vector的迭代器就是原生指针。

而list的迭代器是自定义类型

下面就根据list容器来"配置"一个我们 自己的反向迭代器。

二:反向迭代器

因为我们当时已经写了一个正向迭代器了,那么就不再需要再重新手搓一个反向的了,只需要复用当时正向迭代器的代码即可。所以目前最大的问题就是如何将反向迭代器与正向迭代器互联起来,形成一个联系,通过这个联系使得反向迭代器复用正向迭代器的代码。想必大家都能够想到,使两个"对象"他们产生联系最好用也是唯一的方法就是使用模板类型实例化,即:

cpp 复制代码
template<class Iterator>
class ReverseIterator
{
public:
    ReverseIterator(Iterator it)    // 将"一个正向的迭代器传至反向迭代器内中,对其进行相关特殊操作,使其具有反向迭代器的独特性质"
        :_it(it)
    {}

    // ...
private:
    Iterator _it;
}

即:就相当于=> 通过正向迭代器去适配反向迭代器。

代码如下:

cpp 复制代码
#pragma once

template<class Iterator, class Ref, class Ptr>
class ReverseIterator
{
public:
	typedef ReverseIterator<Iterator, Ref, Ptr> Self;
	
	ReverseIterator(Iterator it)
		:_it(it)
	{}

	// ++ != *
	Self& operator++()
	{
		--_it;
		return *this;
	}
	Self& operator++(int)
	{
		Self tmp(*this);
		--_it;
		return tmp;
	}

	Self& operator--()
	{
		++_it;
		return *this;
	}
	Self& operator--(int)
	{
		Self tmp(*this);
		++_it;
		return tmp;
	}

	Ref operator*()
	{
		Iterator cur = _it;
		return *(--cur);
	}

	Ptr operator->()
	{
		return &(operator*());
	}

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

private:
	Iterator _it;
};

list类内iterator迭代器板块

cpp 复制代码
	template<class T>
	class list
	{
		typedef list_node<T> Node;
	public:
		///
		// Iterators板块
		typedef __list_iterator<T, T&, T*> iterator;
		typedef __list_iterator<T, const T&, const T*> const_iterator;

		typedef ReverseIterator<iterator, T&, T*> reverse_iterator;
		typedef ReverseIterator<const_iterator, const T&, const T*> const_reverse_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); }

		reverse_iterator rbegin() { return reverse_iterator(end()); }
		reverse_iterator rend() { return reverse_iterator(begin()); }

		const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); }
		const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }

        // .........

    }

分析代码:具体式图请移至:CSDN博客汇总/反向迭代器reverse_iterator/CSDN_reverse_iterator/反向迭代器学习板书.png · 阿林/C++代码仓 - 码云 - 开源中国 (gitee.com)

整个list的大概详略图:

三:测试反向迭代器是否适应于每一个容器

3.1:测试string类

cpp 复制代码
	// 测试反向迭代器
	void test_const(const string& st)
	{
		string::const_iterator it = st.begin();
		while (it != st.end())
		{
			cout << *it << " ";
			it++;
		}
		cout << endl;

		string::const_reverse_iterator rit = st.rbegin();
		while (rit != st.rend())
		{
			cout << *rit << " ";
			rit++;
		}
		cout << endl;
	}

	void test_reverse_iterator()
	{
		string str = "hello world";
		string::iterator it = str.begin();
		while (it != str.end())
		{
			cout << *it << " ";
			it++;
		}
		cout << endl;

		string::reverse_iterator rit = str.rbegin();
		while (rit != str.rend())
		{
			cout << *rit << " ";
			rit++;
		}
		cout << endl;

		test_const(str);
	}

// 运行结果:
h e l l o   w o r l d
d l r o w   o l l e h
h e l l o   w o r l d
d l r o w   o l l e h

代码式样图:

3.2:测试vector类

cpp 复制代码
	// 测试反向迭代器
	void test_const(const vector<int>& vc)
	{
		vector<int>::const_iterator it = vc.begin();
		while (it != vc.end())
		{
			cout << *it << " ";
			it++;
		}
		cout << endl;

		vector<int>::const_reverse_iterator rit = vc.rbegin();
		while (rit != vc.rend())
		{
			cout << *rit << " ";
			rit++;
		}
		cout << endl;
	}

	void test_reverse_iterator()
	{
		vector<int> v;
		v.push_back(1);
		v.push_back(2);
		v.push_back(3);
		v.push_back(4);
		v.push_back(15);

		vector<int>::iterator it = v.begin();
		while (it != v.end())
		{
			cout << *it << " ";
			it++;
		}
		cout << endl;

		vector<int>::reverse_iterator rit = v.rbegin();
		while (rit != v.rend())
		{
			cout << *rit << " ";
			rit++;
		}
		cout << endl;

		test_const(v);
	}

// 打印运行结果:
1 2 3 4 15
15 4 3 2 1
1 2 3 4 15
15 4 3 2 1

代码式样图:

3.3:测试list类

cpp 复制代码
	void te(const list<int>& telt)
	{
		list<int>::const_iterator cit = telt.begin();
		while (cit != telt.end())
		{
			cout << *cit << " ";
			++cit;
		}
		cout << endl;

		list<int>::const_reverse_iterator crit = telt.rbegin();
		while (crit != telt.rend())
		{
			cout << *crit << " ";
			++crit;
		}
		cout << endl;
	}	
    
    void test_reverse_iterator()
	{
		list<int> lt;
		lt.push_back(1);
		lt.push_back(2);
		lt.push_back(3);
		lt.push_back(4);
		lt.push_back(5);

		list<int>::iterator it = lt.begin();
		while (it != lt.end())
		{
			cout << *it << " ";
			it++;
		}
		cout << endl;

		list<int>::reverse_iterator rit = lt.rbegin();
		while (rit != lt.rend())
		{
			cout << *rit << " ";
			rit++;
		}
		cout << endl;

		te(lt);
	}

// 运行结果:
1 2 3 4 5
5 4 3 2 1
1 2 3 4 5
5 4 3 2 1

代码式样图:

以上所有的代码都存于:CSDN博客汇总/反向迭代器reverse_iterator/CSDN_reverse_iterator · 阿林/C++代码仓 - 码云 - 开源中国 (gitee.com)

希望宝子们可以点一个stars呀。💖💖💖

相关推荐
岫珩35 分钟前
“由于启动计算机时出现了页面文件配置问题,Windows在你的计算机上创建了一个临时页面文件。。。”的问题解决
windows
李菠菜1 小时前
解决Windows系统下Git克隆时报错“unable to checkout working tree”的方法详解
windows·git
子非衣5 小时前
Windows云主机远程连接提示“出现了内部错误”
服务器·windows
剁椒排骨7 小时前
win11什么都不动之后一段时间黑屏桌面无法显示,但鼠标仍可移动,得要熄屏之后才能进入的四种解决方法
运维·windows·经验分享·计算机外设·win11·win10
李菠菜7 小时前
Windows Terminal 集成 Git Bash 的简洁配置指南
windows·git
大数据魔法师8 小时前
Hadoop生态圈框架部署 - Windows上部署Hadoop
大数据·hadoop·windows
江沉晚呤时9 小时前
深入了解C# List集合及两种常见排序算法:插入排序与堆排序
windows·sql·算法·oracle·c#·排序算法·mybatis
聂 可 以15 小时前
推荐几个可以免费下载视频的软件(Neat Download Manager、蜗牛下载助手、bilidown)
windows·开源软件
菜鸟射手1 天前
QT creater和vs2017文件路径问题
linux·c++·windows·qt
爱编程的鱼1 天前
Windows 各版本查找计算机 IP 地址指南
人工智能·windows·网络协议·tcp/ip·tensorflow