浅谈STL list<T>链表容器和迭代器的使用C++实现
2017-05-26 21:46
826 查看
一、今天简单的实现了STL容器里面的顺序容器list双链表里面的简单应用和迭代器的简单实现方法
包括迭代器的重载方法
二、双向链表的实现需要了解 堆得内存分配问题。堆内存是开发者使用new开辟的空间 需要开发者自己释放掉内存 否者将会存在内存中知道程序结束
所以对内存的释放很重要。当了解了堆和栈的分配之后将会更加容易理解链表的节点的实现方法。
三、关于栈内存的分配将会在博客中发布
下面是测试代码
包括迭代器的重载方法
二、双向链表的实现需要了解 堆得内存分配问题。堆内存是开发者使用new开辟的空间 需要开发者自己释放掉内存 否者将会存在内存中知道程序结束
所以对内存的释放很重要。当了解了堆和栈的分配之后将会更加容易理解链表的节点的实现方法。
三、关于栈内存的分配将会在博客中发布
using namespace std; template class 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); //找到返回 true Nope * 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; } }; template STL_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; } template STL_List::~STL_List() { Destroy(); //删除自己使用 new 分配的堆空间 释放内存 }
下面是测试代码
#include //#include #include "STL_List.h" #include using 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; }
相关文章推荐
- STL--> list 双向循环链表容器 接口使用及介绍。 模拟实现 STL list容器
- C++中防止STL中迭代器失效__map/set等关联容器vector/list/deque等序列容器_如何防止迭代器失效_即erase()的使用
- C++中防止STL中迭代器失效——map/set等关联容器——vector/list/deque等序列容器—如何防止迭代器失效—即erase()的使用
- 【C++ STL应用与实现】7: 如何使用std::forward_list 单链表 (since C++11)
- C++ Greedy Snake的OOP实现 贪食蛇 <list> STL初次学习
- C++中防止STL中迭代器失效__map/set等关联容器vector/list/deque等序列容器_如何防止迭代器失效_即erase()的使用
- C++的标准模板库STL中实现的数据结构之链表std::list的分析与使用
- C++中防止STL中迭代器失效——map/set等关联容器——vector/list/deque等序列容器—如何防止迭代器失效—即erase()的使用
- C++的标准模板库STL中实现的数据结构之链表std::list的分析与使用
- C++--vector<>容器,List<>链表,map<>容器的用法
- C++之STL(三):迭代器类vector::iterator 和 vector::reverse_iterator 的实现、迭代器类型、常用的容器成员
- 【C++】vector容器和list容器中使用单个迭代器的erase函数学习笔记
- C++ STL容器的学习使用(vector、queue、list、set、map)
- Java使用synchronized实现多线程操作list<1>
- [翻译] C++ STL容器参考手册(第二章 <deque>)
- c/c++学习之c++ 中的list <>容器
- C++ STL 容器技术 之 list双向链表容器
- <实例>C++ 将一句话里的单词进行倒置,标点符号不倒换——使用string库实现
- C#中使用BindingList 绑定DataGridView 可以实现动态绑定,优与List<T>集合的绑定
- 从零开始学C++之STL(三):迭代器类vector::iterator 和 vector::reverse_iterator 的实现、迭代器类型、常用的容器成员