浅谈STL list<T>链表容器和迭代器的使用C++实现

来源:互联网 发布:软件系统关键技术指标 编辑:程序博客网 时间:2024/05/22 17:27

    一、今天简单的实现了STL容器里面的顺序容器list双链表里面的简单应用和迭代器的简单实现方法

   包括迭代器的重载方法

    二、双向链表的实现需要了解 堆得内存分配问题。堆内存是开发者使用new开辟的空间 需要开发者自己释放掉内存 否者将会存在内存中知道程序结束

   所以对内存的释放很重要。当了解了堆和栈的分配之后将会更加容易理解链表的节点的实现方法。

  三、关于栈内存的分配将会在博客中发布

    

   

using namespace std;templateclass STL_List{public:STL_List();//list链表指针结构体template struct Nope{ T data;Nope *front; Nope *next; //构造函数 Nope() :data(T()), front(nullptr), next(nullptr) {} Nope(const T &data) :front(nullptr), next(nullptr) { this->data = data; }}; //迭代器类 class Iterator { public: Iterator() {} Iterator(Nope * &p) { head = p; } //复制构造函数 Iterator(Iterator & object) { this->head =object.head ; } //重载前置自增 Iterator operator++() { head = head->next; return *this; } //后置自增    区分前置和后置 后置函数参数列表 多了个(int) Iterator operator++(int) { Iterator temp(*this); head = head->next; return temp; } //重载输出内容friend  T operator*(Iterator &it)   //重载*用friend { return  it.head->data; }  friend  bool  operator!=(Iterator &it, Iterator &it1){if (it.head!= it1.head){return true;}return false;} private: Nope *head; }; //后插void push_back(const T &n_data);//前插void push_front(const T &n_data);//删除指定的值 为空时删除失败 bool remove(T a);//找到返回 trueNope * Search(T a);//返回头结点位置的迭代器对象Iterator begin() { return Iterator(head); } //通过返回Iterator类型  直接调用构造函数//返回尾节点 迭代器对象Iterator end() { return Iterator(tail->next); }  //返回节点最后一位的后一个空指针//摧毁链表释放内存bool Destroy();//测试的函数 运用指针的遍历 只适用于编译器内置类型 不能用于自己开发的类和结构体void show(){Nope *p = head;if (p==nullptr)return;while (p){cout << p->data << endl;p = p->next;}}~STL_List();private:Nope *head;Nope *tail;//利用一个简便的函数自己分配 堆内存空间  Nope *&p 形参使用引用 直接修改调用该函数的指针指向位置无需返回值  bool New_n(Nope *&p, const T &data){p = new Nope(data);return true;}};templateSTL_List::STL_List(){head = nullptr;tail = nullptr;}template void STL_List::push_back(const T &n_data){Nope *temp;     New_n(temp,n_data);  //分配堆空间 //如果链表为空 if (!head) { head = temp; tail = temp; return ; } //不为空时 雷同 push_front(); tail->next = temp; temp->front = tail; tail = temp;return;} template  void STL_List::push_front(const T & n_data) {  Nope *temp;  New_n(temp, n_data);  //如果头结点为空 链表为空  if (nullptr == tail)  {  head = temp;  tail = temp;  return;  }  //链表中有元素时  head->front = temp; //将当前头指针前面指针储存为temp  temp->next = head;//将temp的后一个节点(也就是temp->next) 指向头指针  head = temp;  //跟新头指针到temp的位置 }  template   bool STL_List::remove(T a)  {  Nope *temp= Search(a); //找到删除的指针    if (temp == head)  {  head = temp->next;  head->front = nullptr;  delete temp;  return true;  }  else if (temp == tail)  {  tail = temp->front;  tail->next=nullptr;  //重新让为指针next为空 防止打印时检测不到NULL触发异常  delete temp;  return true;  }  else  {  Nope *p = temp;  temp->front->next = temp->next;  temp->next->front = temp->front;  delete p;  return true;  }  return false;  }  template typename  STL_List::Nope * STL_List::Search(T a)  //前面加上typename将不会产生错误 因为这样编译器才会将  {                                                          //STL_List::Nope * 认定为类型即 Nope*(结构体指针类型)   Nope *p = head;   //创建临时变量进行遍历不会影响到 类中私人数据head节点   if (!head)   return NULL;   //遍历并进行查找   while (p)   {   if (p->data == a)   {   return p;   // 返回 (Nope*) 结构体指针类型   }   p = p->next;      }  return NULL;  } template  bool STL_List::Destroy() { Nope *temp = head; if (!temp) return true;   Nope *p = nullptr;  //删除节点指针临时变量 while (temp) {  p = temp; temp = temp->next; delete p; } if (!temp) { head = nullptr; tail = nullptr; return true; } else  return false; }templateSTL_List::~STL_List(){Destroy();  //删除自己使用 new 分配的堆空间 释放内存}



下面是测试代码
#include//#include#include "STL_List.h"#includeusing namespace std;int main(){STL_List a;STL_List::Iterator itr;//::表示作用域 表示class Iterator 类在STL_List类里面 是其成员内部类a.push_back(22);a.push_back(33);a.push_back(44);a.push_front(77);a.push_front(88);itr = a.begin();for (; itr != a.end(); ++itr){cout << *itr << endl;}//a.show();//a.remove();system("pause");return 0;}