您的位置:首页 > 其它

STL之双向链表及其迭代器简单实现

2015-08-30 21:28 555 查看
最近在看STL,试着写一个自己的链表模板,与STL相比没有使用空间配置器,方法也只实现了几个简单的插入删除元素。但是理清了容器、迭代器之间的关系。代码及测试用例如下。

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便成为野指针。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: