List的链接应用

在学习中,看到了List的另外一种用法,觉得很与众不同、别出心裁,值得小结一下。
1.cList并不是一个容器,有点像一个链接器,将传入的数据串联起来;
2.数据的串联使用的是源结点数据的指针;
3.cList并不会为数据开辟内存空间,保持源数据空间;
4.由于结点数据只是被串联,源结点数据操作独立;
5.模板应用:模板类未实例化时,模板类型可包含(指示)任意变量,编译不会报错。

 

#include <iostream.h>

template <typename TYPE>
class cList
{
public:

  cList(): list_head(0), list_tail(0), end_mark(0), size_(0)
  {
  }

  class Iterator
  {
  public:
    explicit Iterator(TYPE* ptr): cur_p_(ptr)
    {
    }

    void operator++(int) { cur_p_ = cur_p_->next_p_; } 
	//void operator++(int) { cur_p_ = cur_p_->next_p_->next_p_->next_p_; } //next_p_为T成员变量,如果没有实例化LinkList调用,范型T可看做包含任何变量而不会报错。
    void operator++() { cur_p_ = cur_p_->next_p_; } 
    void operator--(int) { cur_p_ = cur_p_->prev_p_; } 
    void operator--() { cur_p_ = cur_p_->prev_p_; } 

    TYPE* operator->() { return cur_p_; }
    TYPE* operator->() const { return cur_p_; }

    TYPE& operator*() {return (*cur_p_);}
  
    bool operator==(const Iterator& rhs ) const { return cur_p_ == rhs.cur_p_; }
    bool operator!=(const Iterator& rhs) const { return !(*this == rhs); }

    TYPE* cur_p_; 
};

typedef Iterator iterator;

//获取链表头
Iterator begin()
{
  return Iterator(list_head);
}

//获取链表尾部标识
Iterator end()
{
  return Iterator(end_mark);
}

//头部插入
void pushFront(TYPE * newNode)
{
  if (list_head == 0)
  {
	list_head = newNode;
	list_tail = newNode;
  }
  else
  {
	TYPE * temp_p        = list_head;
	list_head           = newNode;
	list_head->next_p_  = temp_p;
	temp_p->prev_p_   = list_head;
  }

  ++size_;
}

//尾部插入
void pushBack(TYPE * newNode)
{
  if (list_head == 0)
  {
	list_head = newNode;
	list_tail = newNode;
  }
  else
  {
	list_tail->next_p_ = newNode;
	newNode->next_p_ = end_mark;
	newNode->prev_p_ = list_tail;
	list_tail          = newNode;
  }

  ++size_;
}

//删除最后一个结点
TYPE* detachLastNode()
{
  TYPE * lastNode;

  if (list_tail != list_head)
  {
	lastNode                  = list_tail;
	TYPE * prevNode              = list_tail->prev_p_;
	list_tail->prev_p_->next_p_ = end_mark;
	list_tail                   = prevNode;
  }
  else
  {
	list_head  = 0;
	lastNode = list_tail;
	list_tail  = 0;
  }

  --size_;

  return lastNode;
}

int size() const
{
  return size_;
}

private:
  TYPE* list_head;     //链表头,
  TYPE* list_tail;     //链表尾,尾部插入使用
  TYPE* end_mark;      //链表结束标志,一直为0
  int size_;           //链表大小(长)
};

//链表结点源头类
template <typename TYPE>
class LinkItem
{
public:
  LinkItem()
    : next_p_(0)
    , prev_p_(0)
  {
  }
  
  virtual ~LinkItem() {}

  TYPE* next_p_;
  TYPE* prev_p_;
};

//测试数据1
class cData;
typedef LinkItem<cData> DataLinkItem;
  
class cData : public DataLinkItem
{
  public:
  char a;
};  

typedef cList<cData>    DataLinkedList;
DataLinkedList     dataList_;


//测试数据2,继承了LinkItem,不必定义*next_p_,*prev_p_
class cTestData : public LinkItem<cTestData>
{
  public:
  int a;
};  
cList<cTestData> dataList_2; 

int main()
{
  //传入数据已有数据空间,在LinkList中并不会分配空间。
  //这里使用的数据,是相关联的;实际可以使用不关联的数据。
  cData data[100];
  for(int i = 0; i<100;i++)
  {  
    data[i].a = i;
    dataList_.pushBack(&data[i]);
	  
  }  
  dataList_.detachLastNode();
  for (cList<cData>::iterator it=dataList_.begin();it!=dataList_.end();it++)
  {
	cout<< it->a <<"   ";
  }	    
  
  
  cTestData test_data[100];
  for(int i = 100; i<200;i++)
  {  
    test_data[i].a = i;
    dataList_2.pushBack(&test_data[i]);
  }

  for (cList<cTestData>::iterator it=dataList_2.begin();it!=dataList_2.end();it++)
  {
	cout<< it->a <<"   ";
  }	    
    
  return 1;
}


 

你可能感兴趣的:(List的链接应用)