STL之双向链表及其迭代器简单实现
2015-08-30 21:28
555 查看
最近在看STL,试着写一个自己的链表模板,与STL相比没有使用空间配置器,方法也只实现了几个简单的插入删除元素。但是理清了容器、迭代器之间的关系。代码及测试用例如下。
测试结果如下图
另外给出析构函数的测试截图
执行析构函数前,test1所指链表的head指向0x00319288内存单元
执行析构指令后head被复位为0xfeee,但test1存在与栈上,仍然存在,此时test1便成为野指针。
list_test.h文件 # ifndef LIST_TEST # define LIST_TEST #include<iostream> template <typename T> class listnode { public: listnode<T>* prev; listnode<T>* next; T data; }; template <typename T> class list_iterator { typedef listnode<T>* link_type; public: listnode<T>* node; list_iterator() { node = NULL; } list_iterator(link_type n) { node = n; } bool operator==(const list_iterator& x) const { return node == x.node; } bool operator!=(const list_iterator& x)const { return node != x.node; } T operator*() const { return node->data; } list_iterator operator++() { node = node->next; return *this; } list_iterator operator++(int) { list_iterator tmp=*this; ++*this; return tmp; } list_iterator operator--() { node = node->prev; return *this; } list_iterator operator--(int) { list_iterator tmp = *this; --*this; return tmp; } }; template <typename T> class list_test { typedef listnode<T> list_node; typedef listnode<T>* link_type; typedef list_iterator<T> iterator; public: link_type head; link_type get_node() { return new list_node(); } list_test() { head = get_node(); head->next = head; head->prev = head; } list_test(const list_test& source) { this->head = get_node(); //此处三行不可以直接调用构造函数 this->head->next = head; this->head->prev = head; link_type tmp = source.head->prev; while (tmp != source.head) { this->put_front(tmp->data); tmp = tmp->prev; } } ~list_test() { link_type tmp1 = head; link_type tmp2 = head->prev; while (tmp2 != head) { tmp1 = tmp2->prev; delete tmp2; tmp2 = tmp1; } delete head; head = NULL; } iterator insert(iterator pos,const T value) { link_type temp = get_node(); temp->data = value; temp->next = pos.node; temp->prev = pos.node->prev; pos.node->prev->next = temp; pos.node->prev = temp; return temp; } iterator put_back(const T value) { iterator temp = this->insert(head, value); return temp; } iterator put_front(const T value) { iterator temp = this->insert(head->next, value); return temp; } iterator begin() { return head->next; } iterator end() { return head; } iterator erase(iterator position) { link_type next_node = link_type(position.node->next); link_type prev_node = link_type(position.node->prev); prev_node->next = next_node; next_node->prev = prev_node; delete position.node; return iterator(next_node); } }; # endif
#include <string.h> #include <stdlib.h> #include <stdio.h> #include "list_test.h" using namespace std; int main(int argv, char** argc) { list_test < int > test ; for (int n = 0; n < 5; ++n) { test.put_front(n); //方法测试 } for (auto i = test.begin(); i != test.end();i++) { cout << *i << " "; } cout << endl; list_test < int > *test1 = new list_test < int >(); for (int n = 0; n < 5; ++n) { test1->put_front(n); } for (auto i = test1->begin(); i != test1->end(); i++) { cout << *i << " "; } cout << endl; delete test1; //析构函数测试 list_test < int > test2(test); //拷贝复制函数测试 test2.erase(++test2.begin()); //方法测试 test2.put_back(-1); //方法测试 test2.put_front(5); //方法测试 for (auto i = test2.begin(); i != test2.end(); i++) { cout << *i << " "; } cout << endl; }
测试结果如下图
另外给出析构函数的测试截图
执行析构函数前,test1所指链表的head指向0x00319288内存单元
执行析构指令后head被复位为0xfeee,但test1存在与栈上,仍然存在,此时test1便成为野指针。
相关文章推荐
- 二分查找的两种写法
- CSS选择器的特殊性和LOVE HA
- poj1125floyd
- C#125个基本的面试问答清单
- 给一千万个数据量的文件排序
- 移动端 项目开发经验集锦
- Java基础语法(上)
- Java 时间(日期)相加处理
- 关于敏捷开发的26个心得
- 如何尽量避免引用jQuery
- 【提高学习效率】☞(利用WIN+R 快速打开 软件 及 网页 )
- 深入理解Android消息处理系统——Message、Looper、Handler
- 明天上课了!!!
- 文本、日期、数字的连接
- 给树莓派系统增加看门狗
- WPF 学习资源汇总
- 计算机网络之面试常考
- 基于C#的百度图片批量下载工具
- WPF 学习资源汇总
- HLG 1494网络 (求的割点数目)可做模板