博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C++简易list
阅读量:7107 次
发布时间:2019-06-28

本文共 5454 字,大约阅读时间需要 18 分钟。

list不同于vector。每一个节点的结构须要自行定义,迭代器属于双向迭代器(不是随即迭代器),也须要自行定义。和通用迭代器一样,list的迭代器须要实现的操作有:++、--、*、->、==、!=。节点的数据结构命名为list_node,迭代器的数据结构命名为list_iterator。list中对迭代器的操作不应该使用算数运算,如+2、-3这种操作,仅仅应该使用++、--来移动迭代器。STI版本号的STL使用了一个环形list,list.end()指向一个空白节点(不存放数据)作为尾节点,空白节点的next指针指向第一个节点,空白节点的prev指针指向最后一个节点,这样就能方便的实现begin()和end()操作,当list为空时,空白节点的next和prev均指向自己。这种设计是非常巧妙的,省去了非常多插入、删除操作时须要考虑的边界条件。

#ifndef __MYLIST_H__#define __MYLIST_H__// list节点template 
class list_node {public: list_node
*prev; list_node
*next; Type data;};// list迭代器template
class list_iterator {public: // 迭代器必须定义的五个对应类型 typedef Type value_type; typedef Type* pointer; typedef Type& reference; typedef size_t difference_type; typedef std::bidirectional_iterator_tag iterator_category; list_iterator() : node(NULL) {} list_iterator(list_node
*x) : node(x) {} list_iterator(const list_iterator
&x) : node(x.node) {} // 成员函数尽量加const bool operator== (const list_iterator
&rhs) const { return node == rhs.node; } bool operator!= (const list_iterator
&rhs) const { return !(operator==(rhs)); // 调用现有函数。好的策略 } // 对迭代器接引用返回指向数据的引用 reference operator* () const { return node->data; } pointer operator-> () const { return &(operator*()); // 调用现有函数。好的策略 } list_iterator& operator++ () { node = node->next; return *this; } list_iterator operator++ (int) { list_iterator
old = *this; ++(*this); return old; } list_iterator& operator-- () { node = node->prev; return *this; } list_iterator operator-- (int) { list_iterator
old = *this; --(*this); return old; } // 迭代器通过这个指针与某个节点相联系 list_node
*node;};// list数据结构,SGI中的list是一个环形链表。这里同样// list内部使用list_node訪问每个保存数据的节点。对外则返回给用户一个list_iterator迭代器,这是须要注意的template
class List {public: typedef list_iterator
iterator; // iterator类型是每个容器必备的,应该尽早定义它 typedef size_t size_type; // 构造函数 List() { node = get_node(); // 前后指针都指向自己。表示此list为空 node->next = node; node->prev = node; } iterator begin() { return (list_iterator
)node->next; } iterator end() { return (list_iterator
)node; } bool empty() { return node->next == node; // 參见默认构造函数 } size_type size() { size_type len = 0; distance(begin(), end(), len); return len; } Type& front() { return *begin(); } Type& back() { return *(--end()); } // 插入操作 iterator insert(iterator position, const Type &value) { list_node
*newNode = create_node(value); newNode->next = position.node; newNode->prev = position.node->prev; position.node->prev->next = newNode; position.node->prev = newNode; return (iterator)newNode; // 显示类型转换 } void push_back(const Type &value) { insert(end(), value); } void push_front(const Type &value) { insert(begin(), value); } // 删除操作 iterator erase(iterator position) { list_node
*next = position.node->next; list_node
*prev = position.node->prev; prev->next = next; next->prev = prev; destroy_node(position.node); return (iterator)next; } void pop_back() { iterator tmp = end(); erase(--tmp); } void pop_front() { erase(begin()); } // 清除全部节点 void clear() { list_node
*pnode = node->next; while (pnode != node) { list_node
*tmp = pnode->next; destroy_node(pnode); pnode = tmp; } node->next = node; node->prev = node; } // 删除值为value的全部节点 void remove(const Type &value) { // 为了使用上面的erase,这里定义iterator而不是list_node iterator first = begin(); iterator last = end(); while (first != last) { iterator next = first; ++next; if (*first == value) erase(first); first = next; } }private: // 分配一个节点 list_node
* get_node() { return alloc.allocate(1); } // 释放一个节点 void put_node(list_node
*p) { alloc.deallocate(p, 1); } // 分配并构造一个节点 list_node
* create_node(const Type &value) { list_node
*p = get_node(); alloc.construct(&(p->data), value); return p; } // 析构并释放一个节点 void destroy_node(list_node
*p) { alloc.destroy(&(p->data)); put_node(p); }private: list_node
*node; // 空白节点,指向list.end() static std::allocator< list_node
> alloc; // 空间配置器};// 类中的静态成员一定要记得在类外定义,否则链接时会出错template
std::allocator< list_node
> List
::alloc;#endif

析构函数忘记写了,这里补上:

~List()	{		clear();		if (node != NULL)			delete node;	}

測试代码:

int main(){	List
l; l.push_back(1); l.push_back(2); l.push_back(3); l.push_back(4); l.push_back(5); copy(l.begin(), l.end(), ostream_iterator
(cout, " ")); cout << endl; // 1 2 3 4 5 List
::iterator iter = find(l.begin(), l.end(), 3); iter = l.erase(iter); copy(l.begin(), l.end(), ostream_iterator
(cout, " ")); cout << endl; // 1 2 4 5 l.insert(iter, 123); copy(l.begin(), l.end(), ostream_iterator
(cout, " ")); cout << endl; // 1 2 123 4 5 l.push_front(0); copy(l.begin(), l.end(), ostream_iterator
(cout, " ")); cout << endl; // 0 1 2 123 4 5 l.pop_back(); copy(l.begin(), l.end(), ostream_iterator
(cout, " ")); cout << endl; // 0 1 2 123 4 l.pop_front(); copy(l.begin(), l.end(), ostream_iterator
(cout, " ")); cout << endl; // 1 2 123 4 l.clear(); copy(l.begin(), l.end(), ostream_iterator
(cout, " ")); cout << endl; // null l.push_back(1); l.push_back(2); l.push_back(3); l.push_front(4); l.push_front(5); l.push_front(6); l.remove(1); l.remove(2); l.remove(3); l.remove(5); copy(l.begin(), l.end(), ostream_iterator
(cout, " ")); cout << endl; system("pause"); return 0;}
执行结果:

參考:

《STL源代码剖析》

你可能感兴趣的文章
windows中使用Findwindow函数与FindWindowEx函数来实现自动控制、触发第三方软件事件的方法...
查看>>
浏览器的同源策略和跨域问题
查看>>
SQL SERVER 触发器介绍
查看>>
美国国有企业
查看>>
推送的通知和自定义消息区别
查看>>
c# 解析JSON的几种办法
查看>>
autofs自动挂载
查看>>
JavaWeb学习笔记——过滤器
查看>>
互联网创业原则与创业模式attilax大总结
查看>>
微信小程序想通过场景化缩短路径
查看>>
手把手教你DIY一个春运迁徙图(一)
查看>>
mysql编码问题
查看>>
Web APi之HttpClient注意事项以及建议
查看>>
Webkit内核探究【2】——css简介
查看>>
[Angular] Ngrx/effects, Action trigger another action
查看>>
原生和jQuery的ajax用法
查看>>
【Linux】Linux中 “there are stopped jobs”问题的解决方案
查看>>
[NPM] Use custom config settings in your npm scripts
查看>>
[NPM] Create a node script to replace a complex npm script
查看>>
Kinect2.0获取数据
查看>>