STL源码剖析_读书笔记:第四章 序列式容器 list篇

List:

特点:1)环状双向链表,对于任何位置的元素插入或删除是常数时间,2)插入和接合不会使原有list迭代器失效

list迭代器:不能以普通指针为迭代器,使用bidirectional iterator

插入操作:本质是插入在…之前,新节点位于标示出插入点所指节点的前方,插入前的所有迭代器在插入后有效

 

下面的程序是关于list部分重要函数的实现

#include<iostream>
#include<string>
#include<vector>
#include<iterator>
#include<algorithm>
#include<list>

using namespace std;

//链表节点
template<class T>
struct _list_node
{
 typedef void* void_pointer;
 void_pointer prev;
 void_pointer next;
 T data;
};

//链表迭代器
template<class T,class Ref,class Ptr>
class _list_iterator
{
 typedef _list_iterator<T,T&,T*> iterator;
 typedef _list_iterator<T,Ref,Ptr> self;
 typedef bidirectional_iterator_tag iterator_category;
 typedef T value_type;
 typedef Ptr pointer;
 typedef Ref reference;
 typedef _list_node<T>* link_type;
 typedef size_t size_type;
 typedef ptrdiff_t difference_type;
 link_type node;//指向list的节点
 bool operator==(const self& x) const
 {
  return node == x.node;
 }
 bool operator!=(const self& x) const
 {
  return node != x.node;
 }
 reference operator*()const
 {
  return (*node).data;
 }
 pointer operator->()const
 {
  return &(operator*());
 }
 self& operator++()
 {
  node = (link_type)(node->next);
  return *this;
 }
 self& operator++(int)
 {
  //node = (link_type)(node->next);
  self temp = *this;
  ++(*this);
  return temp;
 }
 self& operator--()
 {
  node = (link_type)(node->prev);
  return *this;
 }
 self& operator--(int)
 {
  //node = (link_type)(node->next);
  self temp = *this;
  --(*this);
  return temp;
 }
};

template<class size_type,class reference,class iterator,class T,class Alloc>
class MaList
{
protected:
 typedef _list_node<T> list_node;
 //typedef simple_alloc<list_node,Alloc> list_node_allocator;//专属空间配置器,每次配置一个节点大小
public:
 typedef list_node* link_type;
protected:
 link_type node;//node是节点指针

protected:
 //分配一个节点
 link_type get_node()
 {
  return list_node_allocator::allocate();
 }
 //释放一个节点
 void put_node(link_type p)
 {
  list_node_allocator::deallocate();
 }
 //配置并构造一个带有值的节点
 link_type create_node(const T& x)
 {
  link_type p = get_node();
  construct(&p->data,x);
  return p;
 }
 //销毁一个节点
 void destroy_node(link_type p)
 {
  destroy(&p->data);
  put_node(p);
 }

 //产生空表
 void empyty_initialize()
 {
  node = get_node;
  node = node->next;//另头尾都指向自己
  node = node->prev;
 }

public:
 MaList(){empty_initialize();}//产生空链表
 iterator begin()
 {
  return (link_type)(node->next);
 }
 iterator end()
 {
  return node;//直接返回的node就是尾端空白节点
 }
 bool empty() const
 {
  return node = node->next;
 }
 size_type size() const
 {
  size_type result = 0;
  distance(begin(),end(),result);
  return result;
 }

 reference front()
 {
  return *begin();
 }
 reference back()
 {
  return *(-end());
 }

 void push_back(const T& x)
 {
  insert(end(),x);
 }
 //在双向链表中插入节点
 iterator insert(iterator pos,const T& x)
 {
  link_type temp = create_node(x);
  temp->next = pos.node;
  temp->prev = pos.node->prev;
  (link_type(pos.node->prev))->next = temp;
  pos.node->prev = temp;
  return temp;
 }

 void push_front(const T& x)
 {
  insert(begin(),x);
 }

 //void push_back(const T& x)
 //{
 // //insert(--end(),x);//插入的节点作为尾节点
 // insert(end(),x);
 //}

 iterator erase(iterator pos)
 {
  link_type next_node = link_type(pos.node->next);
  link_type prev_node = link_type(pos.node->prev);
  prev_node->next = next_node;
  next_node->prev = prev_node;
  destroy_node(pos.node);
  return iterator(next_node);
 }

 void pop_front()
 {
  erase(begin());
 }

 void pop_back()
 {
  //erase(end());不能直接删,否则后面不好用了
  iterator temp = end();
  erase(--temp);
 }

 void clear()
 {
  link_type cur = (link_type)node->next;
  while(cur!=node)
  {
   link_type temp = cur;
   cur = (link_type)cur->next;
   destroy_node(temp);
  }
  //恢复node原始状态
  node->next = node;
  node->prev = node;
 }
 //移除数值相同的连续元素
 void unique()
 {
  if(begin()==end())//空链表什么也不做
  {
   return;
  }
  iterator first = begin();
  iterator next = first;
  while(++next!=end())
  {
   if(*first==*next)
   {
    erase(next);
   }
   else
   {
    first = next;//调整指针
    //修正区域范围
   }
  }
 }

 //将[first,last]范围内所有元素移到pos前面
 void transfer(iterator pos,iterator first,iterator last)
 {
  if(pos!=last)
  {
   ((link_type)(last.node->prev)).next = pos.node;
   ((link_type)(first.node->prev)).next = last.node;
   ((link_type)(pos.node->prev)).next = first.node;
   link_type temp = link_type(pos.node->prev);
   pos.node->prev = last.node->prev;
   last.node->prev = first.node->prev;
   first.node->prev = temp;
  }
 }
};


int main(int argc,char *argv[])
{
// int i;
 int ia[] = {9,8,7,6,5,4,3,2,1,0};
 list<int> iList(ia,ia+10);
 cout<<"list size:"<<iList.size()<<endl;
 list<int>::iterator it;
 it = find(iList.begin(),iList.end(),4);
 int ia1[] = {6,6,6,6};
 list<int> iList1(ia1,ia1+4);
 iList.splice(it,iList1);
 copy(iList.begin(),iList.end(),ostream_iterator<int>(cout,"\t"));

 getchar();
 return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值