容器通过提供大致统一的迭代器界面供外界访问数据,而算法只作用于迭代器,从而摆脱对具体类型的依赖。
实例1: 带有迭代器的双向链表简易实现:
#include<iostream>
#include<stdexcept>
_Pragma ("once")
template<typename T> class List;
template<typename N>
class Iterator{
public:
using value_type=typename N::value_type;
using reference_type=typename N::reference_type;
using const_reference_type=typename N::const_reference_type;
using self_type=Iterator<N>;
Iterator():pos(0){}
Iterator(N* p):pos(p){}
bool operator !=(self_type const& right) const{
return pos!=right.pos;
}
bool operator ==(self_type const& right) const{
return pos==right.pos;
}
self_type& operator++(){
if(pos){
pos=pos->next;
}
return *this;
}
reference_type operator*() throw(std::runtime_error){
if(pos)
return pos->value;
else
throw (std::runtime_error("defreferenceing null iterator"));
}
private:
N* pos;
template<typename T> friend class list;
};
template<typename T>
class Node{
public:
using value_type=T;
using reference_type=T&;
using const_reference_type=const T&;
T value;
Node* prev;
Node* next;
Node(T const& v,Node* p,Node* n)
:value(v),prev(p),next(n){}
};
template<typename T>
class List{
private:
using node_type=Node<T>;
node_type* head;
public:
using value_type=T;
using iterator=Iterator<node_type>;
List():head(nullptr){}
~List(){
while(head){
node_type* n=head;
head=head->next;
delete n;
}
}
void push_front(T const& v){
head=new node_type(v,nullptr,head);
if(head->next){
head->next->prev=head;
}
}
void pop_front(T& v){
if(head){
node_type* temp=head;
head=head->next;
if(head)
head->prev=nullptr;
v=temp->value;
delete temp;
}
}
void insert(iterator it,T const& v){
node_type* n=it.pos;
if(n){
node_type* new_node=new node_type(v,n,n->next);
new_node->next->prev=new_node;
n->next=new_node;
}
}
void erase(iterator& it){
node_type* n=it.pos;
++it;
if(n){
if(n->next)
n->next->prev=n->prev;
if(n->prev)
n->prev->next=n->next;
delete n;
}
}
bool empty() const{
return head==nullptr;
}
iterator begin(){
return iterator(head);
}
iterator end(){
return iterator();
}
};
int main(){
List<int> myList;
int x=10;
myList.push_front(x);
int y;
myList.pop_front(y);
std::cout<<myList.empty()<<" "<<y<<std::endl;
return 0;
}
实例2:带有迭代器的简易set实现:
#include<stdexcept>
#include<iostream>
using namespace std;
_Pragma("once")
template<typename N>
class Iterator{
private:
const N* pos;
public:
using value_type=typename N::value_type;
using const_reference_type=typename N::const_reference_type;
using self_type=Iterator<N>;
Iterator():pos(nullptr){}
Iterator(const N* p):pos(p){}
bool operator==(self_type const& right) const{
return pos==right.pos;
}
self_type& operator++(){
if(pos){
if(pos->right){
pos=pos->right;
while(pos->left) pos=pos->left;
}
else{
while((pos->parent)&&(pos->parent->right==pos))
pos=pos->parent;
pos=pos->parent;
}
}
return *this;
}
const_reference_type operator*() const throw(std::runtime_error){
if(pos) return pos->value;
else throw std::runtime_error("deferencing null iterator");
}
};
template<typename N>
bool operator!=(Iterator<N> const &left,Iterator<N> const &right){
return !(left==right);
}
template<typename T>
class Node{
public:
using value_type=T;
using reference_type=T&;
using const_reference_type=const T&;
T value;
Node* parent;
Node* left;
Node* right;
Node(T const& v,Node* p,Node* l,Node* r)
:value(v),parent(p),left(l),right(r){}
~Node(){
if(left) delete left;
if(right) delete right;
}
};
template<typename T>
class Set{
private:
using node_type=Node<T>;
node_type* root;
public:
using value_type=T;
using const_iterator=Iterator<node_type>;
Set():root(nullptr){}
~Set(){
if(root)
delete root;
}
bool insert(T const& v){
node_type** n=&root;
node_type* p=nullptr;
while(*n){
if(v==(*n)->value)
return false;
else{
p=*n;
n=v<(*n)->value?&((*n)->left):&((*n)->right);
}
}
*n=new node_type(v,p,nullptr,nullptr);
return true;
}
bool has(T const& v){
node_type* n=root;
while(n){
if(v==n->value)
return true;
n=v<n->value?n->left:n->right;
}
return false;
}
bool empty() const{
return root==nullptr;
}
const_iterator begin(){
node_type* n=root;
while(n->left) n=n->left;
return const_iterator(n);
}
const_iterator end() const{
return const_iterator();
}
};
int main(){
Set<int> mySet;
int x=10;
mySet.insert(x);
cout<<mySet.has(int(10))<<" "<<mySet.empty()<<endl;
return 0;
}