使用STL vector 接口:
#include <iostream>
#include <vector>
using namespace std;
void TestVector( )
{
vector<int> v1;
v1.push_back( 1 );
v1.push_back( 2 );
v1.push_back( 3 );
v1.push_back( 4 );
PrintVector( v1 );
vector<int> v2( 3, 10 );
PrintVector( v2 );
}
int main( )
{
TestVector( );
return 0;
}
//封装是为了复用,调用这个函数即可,不用每次都写打印代码
void PrintVector( vector<int>& v1 )//引用 //加 const 编译不通过 如果要编译通过 1.普通迭代器(可读,可写) 2.const 迭代器(可读) 3.反向迭代器(反着遍历)
{
//迭代器 是 类似指针的一个对象 -> 和智能指针相似
//[begin, end) 迭代器是 左闭右开 区间
vector<int>::iterator it/*迭代器对象*/; //如果用const_iterator 则 ++(*it) 会报错, 因为不能给常量赋值
it = v1.begin( );
while ( v1.end( ) != it )
{
//1.打印
cout << *it << " ";
++it;
//2.打印奇数
//if ( 0 != *it % 2 )
//{
// cout << *it << " ";
//}
/*++it;*/
//3.每个数加 1
//++(*it);
//++it;
}
cout << endl;
//反向迭代器 是 倒着走
vector<int>::const_reverse_iterator rIt = v.rbegin( );
while ( v.rend() != rIt )
{
cout << *rIt << " ";
++rIt;
}
cout << endl;
}
list:
#include <iostream>
#include <list>
using namespace std;
void TestList( );
void PrintList( list<int>& l );
int main( )
{
TestList( );
return 0;
}
void TestList( )
{
list<int> l1;
l1.push_back( 1 );
l1.push_back( 2 );
l1.push_back( 3 );
l1.push_back( 4 );
list<int> l2( 5, 1 ); //带值的初始化
}
void PrintList( /*const*/list<int>& l )
{
list<int>::/*const_*/iterator it = l.begin( );
while ( l.end( ) != it )
{
cout << *it << " ";
/* *it = 10; *///如果是 const迭代器 则不能赋值
++it;
}
cout << endl;
}
模拟实现:STL 中 名字为 list, 我们模拟实现名字为 List
:
//链表的四次实现
//1.C -> 基本实现和面试题
//2.C++ -> 面向对象 C 和 C++区别 深拷贝
//3.C++ -> 泛型编程 + T -- string
//4.数据结构 -- STL
//搜索 ctrl + f -> 快捷键查找F3 -> 倒着搜索 shift + F3
//名称 小写加下划线
#pragma once//防止重定义
#include "Iterator.h"//为了实现 List 反向迭代器
template<class T>
struct __ListNode
{
T _data;
__ListNode<T>* _next;
__ListNode<T>* _prev;
__ListNode( const T& x )
:_data( x )
,_next( NULL )
,_prev( NULL )
{}
};
//迭代器 是一个 类 通过 运算符重载 使它像指针一样使用
//T T& T* 有了 T 为什么 还有传 T&, T* ,为了实现 const迭代器
//T const T& const T*
template<class T, class Ref, class Ptr>
struct __ListIterator // sizeof(__ListIterator) == 4 因为它里面还是一个指向节点的指针,只是通过封装1让它变为新的类型, 大小不变,为4
{
typedef __ListNode<T> Node;
typedef __ListIterator<T, Ref, Ptr> Self;
typedef Ref Reference;//反向迭代器
typedef Ptr Pointer;//反向迭代器
__ListIterator( Node* node )
:_node( node )
{}
Ref operator*( )//1.出了作用域存在,所以传&。而且为了效率, 如果不传引用, string对象, 深拷贝。 2. 引用是为了可以更改数据
{
return _node->_data;
}
const Ref operator*( )//const 迭代器 中 用 const 修饰 Ref即可。
{
return _node->_data;
}
Ptr operator->( )
{
return &_node->_data;
}
Self& operator++( )//前置++ //注意后置 前置的区别
{
_node = _node->_next;
return *this;
}
Self operator++( int )//后置++ 不能给& 因为出了作用域对象不存在,不能给引用
{
Self tmp( _node );//构造 1
//Self tmp( *this );//拷贝构造 2
_node = _node->_next;
return tmp;
}// 1 or 2 时 构造 or 拷贝构造, 然后 return 时, 再拷贝构造个临时对象返回。
Self& operator--( )
{
_node = _node->_prev;
return *this;
}
Self operator--( int )
{
Node* cur = _node;
_node = _node->_prev;
return Self( cur );//先构造出一个对象,再拷贝构造出临时对象返回,但是他们是在返回步骤的一个表达式里,编译器会进行优化 -> 不会先构造再拷贝构造而是 直接构造临时对象 作为返回值, 所以 这里的代码 比 后置++实现的好.
}
bool operator!=( const Self& s ) const
{
return /*this->*/_node !