关闭

stl容器list部分实现

标签: stllist源码iterator
179人阅读 评论(0) 收藏 举报
分类:
#include <iostream>
#include <stdexcept>
#include <cstring>
using namespace std;
// 双向线性链表容器模板
template<typename T>
class List {
public:
	// 构造、析构、拷贝构造、拷贝赋值
	List (void) : m_head (NULL), m_tail (NULL) {}
	~List (void) {
		clear ();
	}
	List (const List& that) : m_head (NULL),
		m_tail (NULL) {
		for (Node* node = that.m_head; node;
			node = node->m_next)
			push_back (node->m_data);
	}
	List& operator= (const List& that) {
		if (&that != this) {
			List list (that);
			swap (m_head, list.m_head);
			swap (m_tail, list.m_tail);
		}
		return *this;
	}
	// 获取首元素
	T& front (void) {
		if (empty ())
			throw underflow_error ("链表下溢!");
		return m_head->m_data;
	}
	const T& front (void) const {
		return const_cast<List*> (this)->front ();
	}
	// 向首部压入
	void push_front (const T& data) {
		m_head = new Node (data, NULL, m_head);
		if (m_head->m_next)
			m_head->m_next->m_prev = m_head;
		else
			m_tail = m_head;
	}
	// 从首部弹出
	void pop_front (void) {
		if (empty ())
			throw underflow_error ("链表下溢!");
		Node* next = m_head->m_next;
		delete m_head;
		m_head = next;
		if (m_head)
			m_head->m_prev = NULL;
		else
			m_tail = NULL;
	}
	// 获取尾元素
	T& back (void) {
		if (empty ())
			throw underflow_error ("链表下溢!");
		return m_tail->m_data;
	}
	const T& back (void) const {
		return const_cast<List*> (this)->back ();
	}
	// 向尾部压入
	void push_back (const T& data) {
		m_tail = new Node (data, m_tail);
		if (m_tail->m_prev)
			m_tail->m_prev->m_next = m_tail;
		else
			m_head = m_tail;
	}
	// 从尾部弹出
	void pop_back (void) {
		if (empty ())
			throw underflow_error ("链表下溢!");
		Node* prev = m_tail->m_prev;
		delete m_tail;
		m_tail = prev;
		if (m_tail)
			m_tail->m_next = NULL;
		else
			m_head = NULL;
	}
	// 删除所有匹配元素
	void remove (const T& data) {
		for (Node* node = m_head, *next; node;
			node = next) {
			next = node->m_next;
			if (equal (node->m_data, data)) {
				if (node->m_prev)
					node->m_prev->m_next =
						node->m_next;
				else
					m_head = node->m_next;
				if (node->m_next)
					node->m_next->m_prev =
						node->m_prev;
				else
					m_tail = node->m_prev;
				delete node;
			}
		}
	}
	// 清空
	void clear (void) {
		for (Node* next; m_head; m_head = next) {
			next = m_head->m_next;
			delete m_head;
		}
		m_tail = NULL;
	}
	// 判空
	bool empty (void) const {
		return ! m_head && ! m_tail;
	}
	// 获取大小
	size_t size (void) const {
		size_t count = 0;
		for (Node* node = m_head; node;
			node = node->m_next)
			++count;
		return count;
	}
	// 插入输出流
	friend ostream& operator<< (ostream& os,
		const List& list) {
		for (Node* node = list.m_head; node;
			node = node->m_next)
			os << *node;
		return os;
	}
private:
	// 节点
	class Node {
	public:
		Node (const T& data = 0, Node* prev = NULL,
			Node* next = NULL) : m_data (data),
			m_prev (prev), m_next (next) {}
		friend ostream& operator<< (ostream& os,
			const Node& node) {
			return os << '(' << node.m_data << ')';
		}
		T m_data; // 数据
		Node* m_prev; // 前指针
		Node* m_next; // 后指针
	};
	bool equal (const T& a, const T& b) const {
		return a == b;
	}
	Node* m_head; // 头指针
	Node* m_tail; // 尾指针
public:
	// 正向迭代器
	class Iterator {
	public:
		Iterator (Node* head = NULL,
			Node* tail = NULL, Node* node = NULL) :
			m_head (head), m_tail (tail),
			m_node (node) {}
		bool operator== (const Iterator& it) const {
			return m_node == it.m_node;
		}
		bool operator!= (const Iterator& it) const {
			return ! (*this == it);
		}
		Iterator& operator++ (void) {
			if (m_node)
				m_node = m_node->m_next;
			else
				m_node = m_head;
			return *this;
		}
		const Iterator operator++ (int) {
			Iterator old = *this;
			++*this;
			return old;
		}
		Iterator& operator-- (void) {
			if (m_node)
				m_node = m_node->m_prev;
			else
				m_node = m_tail;
			return *this;
		}
		const Iterator operator-- (int) {
			Iterator old = *this;
			--*this;
			return old;
		}
		T& operator* (void) const {
			return m_node->m_data;
		}
		T* operator-> (void) const {
			return &**this;
		}
	private:
		Node* m_head;
		Node* m_tail;
		Node* m_node;
		friend class List;
	};
	Iterator begin (void) {
		return Iterator (m_head, m_tail, m_head);
	}
	Iterator end (void) {
		return Iterator (m_head, m_tail);
	}
	Iterator insert (Iterator loc, const T& data) {
		if (loc == end ()) {
			push_back (data);
	   		return Iterator (m_head, m_tail,m_tail);
		}
		else {
			Node* node = new Node (data,
				loc.m_node->m_prev, loc.m_node);
			if (node->m_prev)
				node->m_prev->m_next = node;
			else
				m_head = node;
			node->m_next->m_prev = node;
			return Iterator (m_head, m_tail, node);
		}
	}
	Iterator erase (Iterator loc) {
		if (loc == end ())
			throw invalid_argument ("无效迭代器!");
		if (loc.m_node->m_prev)
			loc.m_node->m_prev->m_next =
				loc.m_node->m_next;
		else
			m_head = loc.m_node->m_next;
		if (loc.m_node->m_next)
			loc.m_node->m_next->m_prev =
				loc.m_node->m_prev;
		else
			m_tail = loc.m_node->m_prev;
		Node* next = loc.m_node->m_next;
		delete loc.m_node;
		return Iterator (m_head, m_tail, next);
	}
};
// 针对const char*的特化
template<>
bool List<const char*>::equal (const char* const& a,
	const char* const& b) const {
	return strcmp (a, b) == 0;
}
// 测试用例
int main (void) {
	try {
		List<int> list1;
		list1.push_front (20);
		list1.push_front (10);
		list1.push_back (30);
		list1.push_back (40);
		cout << list1 << endl;
		cout << list1.front () << ' ' <<
			list1.back () << endl;
		list1.pop_front ();
		list1.pop_back ();
		cout << list1 << endl;
		++list1.front ();
		--list1.back ();
		cout << list1 << endl;
		list1.push_back (21);
		list1.push_back (25);
		list1.push_back (21);
		list1.push_back (21);
		cout << list1 << endl;
		list1.remove (21);
		cout << list1 << endl;
		List<int> list2 = list1;
		cout << list2 << endl;
		list2.back () = 100;
		cout << list2 << endl;
		cout << list1 << endl;
		list2 = list1;
		cout << list2 << endl;
		list2.front () = 100;
		cout << list2 << endl;
		cout << list1 << endl;
		cout << list1.size () << endl;
		list1.clear ();
		cout << list1 << endl;
		cout << boolalpha << list1.empty () << endl;
//		List<string> list3;
		List<const char*> list3;
		list3.push_back ("beijing");
		list3.push_back ("tianjin");
		list3.push_front ("tianjin");
		list3.push_back ("shanghai");
		list3.push_back ("beijing");
		cout << list3 << endl;
		list3.remove (string ("beijing").c_str ());
		cout << list3 << endl;
		for (List<const char*>::Iterator it =
			list3.begin (); it != list3.end ();
			++it)
			cout << *it << ' ';
		cout << endl;
		List<const char*>::Iterator it =
			list3.begin ();
		it++;
		it = list3.insert (it, "chongqing");
		cout << list3 << endl;
		list3.erase (it);
		cout << list3 << endl;
	}
	catch (exception& ex) {
		cout << ex.what () << endl;
		return -1;
	}
	return 0;
}

0
0
查看评论
发表评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

C++ STL 几个容器的底层实现 收藏一下

STL底层数据结构实现 C++ STL 的实现: 1.vector      底层数据结构为数组 ,支持快速随机访问 2.list           ...
  • single_wolf_wolf
  • single_wolf_wolf
  • 2016-10-18 22:46
  • 3213

带你深入理解STL之List容器

上一篇博客中介绍的vector和数组类似,它拥有一段连续的内存空间,并且起始地址不变,很好的支持了随机存取,但由于是连续空间,所以在中间进行插入、删除等操作时都造成了内存块的拷贝和移动,另外在内存空间...
  • terence1212
  • terence1212
  • 2016-08-24 17:29
  • 2577

C++ STL内部简单细节整理

对于使用C++语言进行项目开发的同学,STL必然是必须掌握并且熟练的技术。除了能够熟练使用,我们当然也有必要知道其内部实现原理。当然,对于新手或者并属于一线开发者的同学,一下子看懂STL源码是不现实的...
  • njustzj001
  • njustzj001
  • 2015-06-28 21:04
  • 1502

用C++实现STL容器list

用C++实现STL容器list
  • yaoxiaokui
  • yaoxiaokui
  • 2015-10-17 15:35
  • 239

STL容器中list与迭代器iterator的模拟实现

list在容器中结构是有一个头结点_head,头结点指向第一个结点,尾结点指向头结点,它为双向循环链表,在其中它有自己的迭代器可以类似于智能指针,用于数据的访问和算法的配合。 代码实现: #inc...
  • L_XRUI
  • L_XRUI
  • 2016-12-30 16:03
  • 1140

C++STL库list容器简单实现

针对C++应届生应聘笔试可能会涉及list容器的简单实现,特献上此文,希望能给有需要的朋友一些裨益,具体看代码讲解: #include #include using namespace st...
  • qq_31766907
  • qq_31766907
  • 2015-12-16 19:20
  • 184

STL list容器实现集合的交和并

集合的交:#include #include #include using namespace std; template list intersection(const list &L1,const...
  • u013021513
  • u013021513
  • 2014-12-21 20:16
  • 355

使用STL中的list容器实现单链表的操作

#include #include #include using namespace std; void Print(int &item) { cout<<item<<" "; } int mai...
  • adminabcd
  • adminabcd
  • 2015-06-27 16:59
  • 953

STL之list容器的实现框架

list的底层采用数据结构是环形的双向链表, 相对于vector容器,list容器插入和删除操作付出的代价要比vector容器小得多,但是list带有链表的天生弱点,就是不支持随机访问。从内置的迭代器...
  • JXH_123
  • JXH_123
  • 2014-06-20 19:06
  • 658

stl容器区别: vector list deque set map-底层实现

在STL中基本容器有: vector、list、deque、set、map set 和map都是无序的保存元素,只能通过它提供的接口对里面的元素进行访问 set:集合, 用来判断某一个元素...
  • wangzengdi
  • wangzengdi
  • 2014-06-15 12:03
  • 667
    个人资料
    • 访问:140978次
    • 积分:1755
    • 等级:
    • 排名:千里之外
    • 原创:22篇
    • 转载:96篇
    • 译文:0篇
    • 评论:16条
    文章分类
    最新评论