【C++精简版回顾】21.迭代器,实现迭代器

1.什么是迭代器?

用来遍历容器,访问容器数据。

2.迭代器使用

1.初始化

//初始化
list<int> mylist;//list的整数对象
list<int>::iterator iter;//list内部类,迭代器对象(正向输出)
list<int>::reverse_iterator riter;//list内部类,迭代器对象(反向输出)
int array[5] = { 1,2,3,4,5 };

2.添加数据

//添加数据到list中
mylist.assign(array, array + 5);

3.正向输出

//正向输出
for (iter = mylist.begin();iter != mylist.end();iter++) {
	cout << *iter << "\t" ;
}

4.反向输出

for (riter = mylist.rbegin();riter != mylist.rend();riter++) {
	cout << *riter << "\t";
}

结果:

3.实现一个反向迭代器

1.建立一个节点(用来存储数据)

template<class type>
struct Node {
	type data;
	Node<type>* left;
	Node<type>* right;
	Node(type data):data(data),left(nullptr),right(nullptr){}
	Node(type data, Node<type>*left, Node<type>*right) :data(data) ,left(left),right(right){}
};

2.事项简单的list类(类中包括一个反方向的迭代器)

template<class type>
class list {
public:
	list() {}
	//因为需要反向迭代,所以需要建立双链表
	void assign(type* begin,type* end) {
		while (begin != end) {
			Node<type>* node = new Node<type>(*begin);
			if (size == 0) {
				listhead = node;
				listend = node;
				node->left = node;
				node->right = node;
			}
			else {
				listend->right = node;
				node->right = listhead;
				node->left = listend;
				listend = node;
				listhead->left = node;				
			}
			size++;
			begin++;
		}
	}
	//rbegin,rend
	Node<type>* rbegin() {
		return listend;
	}
	Node<type>* rend() {
		return listhead;
	}
//反方向的迭代器-----------------------------------------
	class reverse_iterator {
	public:
		void operator=(Node<type>* node) {
			this->pmove = node;
		}
		bool operator!=(Node<type>* node) {
			return this->pmove != node;
		}
		reverse_iterator& operator++(int) {
			this->pmove = this->pmove->left;
			return (*this);
		}
		type operator*() {
			return this->pmove->data;
		}
	protected:
		Node<type>* pmove;
	};
protected:
	Node<type>* listhead;
	Node<type>* listend;
	int size=0;
};

3.对上述代码的解释

(1)插入代码,普通指针指向修改

	//因为需要反向迭代,所以需要建立双链表
	void assign(type* begin,type* end) {
		while (begin != end) {
			Node<type>* node = new Node<type>(*begin);
			if (size == 0) {
				listhead = node;
				listend = node;
				node->left = node;
				node->right = node;
			}
			else {
				listend->right = node;
				node->right = listhead;
				node->left = listend;
				listend = node;
				listhead->left = node;				
			}
			size++;
			begin++;
		}
	}

(2)单目运算符的重载一般在类中直接实现,使用友元函数会增加传参

class reverse_iterator {
	public:

		void operator=(Node<type>* node) {
			this->pmove = node;
		}

		bool operator!=(Node<type>* node) {
			return this->pmove != node;
		}

		reverse_iterator& operator++(int) {
			this->pmove = this->pmove->left;
			return (*this);
		}

		type operator*() {
			return this->pmove->data;
		}
	protected:
		Node<type>* pmove;
	};

结果:

整个代码: 瑕疵之处

1.析构函数没有使用,目前不太清楚应该在哪里开始析构。

2.数据1输出不出来,因为下面代码在头节点会报0。

解决方法:使用一个头节点(不存放数据)

bool operator!=(Node<type>* node) {
	return this->pmove != node;
}

附上总体代码

1.main

#include"标头.h"
#include<iostream>
#include<stdlib.h>
using namespace std;
int main() {
	//list链表 反向输出 迭代器
	list<int>::reverse_iterator riter;
	//list<int> mylist = { 1,2,3,4,5,6 };
	int arr[6] = { 1,2,3,4,5,6 };
	list<int> mylist;
	mylist.assign(arr, arr + 6);
	for (riter = mylist.rbegin();riter != mylist.rend();riter++) {
		cout << *riter << "\t";
	}
	cout << endl;
	return 0;
}

2.实现

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<stdlib.h>
using namespace std;
template<class type>
struct Node {
	type data;
	Node<type>* left;
	Node<type>* right;
	Node(type data):data(data),left(nullptr),right(nullptr){}
	Node(type data, Node<type>*left, Node<type>*right) :data(data) ,left(left),right(right){}
};
template<class type>
class list {
public:
	list() {}
	//因为需要反向迭代,所以需要建立双链表
	void assign(type* begin,type* end) {
		while (begin != end) {
			Node<type>* node = new Node<type>(*begin);
			if (size == 0) {
				listhead = node;
				listend = node;
				node->left = node;
				node->right = node;
			}
			else {
				listend->right = node;
				node->right = listhead;
				node->left = listend;
				listend = node;
				listhead->left = node;				
			}
			size++;
			begin++;
		}
	}
	//rbegin,rend
	Node<type>* rbegin() {
		return listend;
	}
	Node<type>* rend() {
		return listhead;
	}
	class reverse_iterator {
	public:
		void operator=(Node<type>* node) {
			this->pmove = node;
		}
		bool operator!=(Node<type>* node) {
			return this->pmove != node;
		}
		reverse_iterator& operator++(int) {
			this->pmove = this->pmove->left;
			return (*this);
		}
		type operator*() {
			return this->pmove->data;
		}
	protected:
		Node<type>* pmove;
	};
protected:
	Node<type>* listhead;
	Node<type>* listend;
	int size=0;
};
相关推荐
Amo Xiang14 分钟前
Python 常用模块(四):shutil模块
开发语言·python
Happy鱿鱼31 分钟前
C语言-数据结构 有向图拓扑排序TopologicalSort(邻接表存储)
c语言·开发语言·数据结构
KBDYD101032 分钟前
C语言--结构体变量和数组的定义、初始化、赋值
c语言·开发语言·数据结构·算法
计算机学姐34 分钟前
基于python+django+vue的影视推荐系统
开发语言·vue.js·后端·python·mysql·django·intellij-idea
Crossoads1 小时前
【数据结构】排序算法---桶排序
c语言·开发语言·数据结构·算法·排序算法
扎克begod1 小时前
JAVA并发编程系列(9)CyclicBarrier循环屏障原理分析
java·开发语言·python
code bean1 小时前
【C#基础】函数传参大总结
服务器·开发语言·c#
阳光阿盖尔1 小时前
EasyExcel的基本使用——Java导入Excel数据
java·开发语言·excel
蔚一1 小时前
Java设计模式—面向对象设计原则(三) -----> 依赖倒转原则DIP(完整详解,附有代码+案例)
java·开发语言·设计模式·intellij-idea·依赖倒置原则
liang89991 小时前
SpringSecurity原理解析(七):权限校验流程
java·开发语言