C++实现单链表

概述

该单链表的实现具有迭代器(一个嵌套类)以及,增、删、改、查、反转操作,所有关于指针的操作均隐藏在迭代器里。

代码实现

template <class Object>
class LinkList {
private:
	struct Node {
		Object data;
		struct Node * next;
		Node(const Object & d = Object(), Node *p = nullptr) : data(d), next(p) {  }
	};

public:
	class const_iterator {
	public:
		const_iterator() : current(nullptr) { }
		const Object & operator*() const { return retrieve(); }
		const_iterator & operator++()
		{
			current = current != nullptr ? current->next : nullptr;
			return *this;
		}
		const_iterator operator++(int)
		{
			const_iterator old = *this;
			++(*this);
			return old;
		}
		bool operator==(const const_iterator & rhs) const 
		{
			return current == rhs.current;
		}
		bool operator!=(const const_iterator & rhs) const
		{
			return !(*this == rhs);
		}
	protected:
		Node * current;
		Object & retrieve() const { return current->data; }
		const_iterator(Node * p) : current(p) { }
		friend class LinkList<Object>;
	};

	class iterator : public const_iterator {
	public:
		iterator() {  }

		Object & operator*()
		{
			return const_iterator::retrieve();
		}

		const Object & operator*() const
		{
			return const_iterator::operator*();
		}
		iterator & operator++ ()
		{
			const_iterator::current = const_iterator::current != nullptr ? const_iterator::current->next : nullptr;
			return *this;
		}
		iterator operator++(int)
		{
			iterator old = *this;
			++(*this);
			return old;
		}

	protected:
		iterator(Node *p) : const_iterator(p) { }
		friend class LinkList<Object>;
	};

public:
	LinkList() {  init();}
	LinkList(const LinkList & rhs) { init(); *this = rhs; }
	~LinkList() 
	{ 
		clear(); 
		theSize = 0; 
		delete head;
		
	}
	const LinkList & operator=(const LinkList & rhs) {
		if (this == &rhs) {
			return *this;
		}
		clear();
		iterator it(head);
		for (const_iterator itr = rhs.begin(); itr != rhs.end(); itr++) {
			it = insert(it, *itr);
		}
		return *this;
	}

	void clear() {
		while (!empty()) {
			pop_front();
		}
	}

	iterator begin() { return iterator(head->next); }
	const_iterator begin() const { return const_iterator(head->next); }
	iterator end() { return iterator(); }
	const_iterator end() const { return const_iterator(); }
	int size() const { return theSize; }
	bool empty() const { return size() == 0; }
	iterator insert(iterator pre, const Object &X) {
		if (nullptr == pre.current) {
			throw std::runtime_error("insert: nullptr");
		}
		
		Node * p = new Node(X, pre.current->next);
		pre.current->next = p;
		theSize++;
		return iterator(p);
	}

	iterator findPre(const Object & X) {
		iterator it(head);
		while (it.current->next != nullptr && it.current->next->data != X) {
			it++;
		}
		return it;
	}

	iterator find(const Object & X) {
		iterator ret = findPre(X);
		return ++ret;
	}

	void deleteEle(const Object & X) {
		iterator it = findPre(X);
		if (it.current->next != nullptr) {
			iterator temp = it.current->next;
			it.current->next = temp.current->next;
			delete temp.current;
			theSize--;
		}
	}

	iterator erase(iterator it) {
		Node * p = it.current;
		if (nullptr == p) {
			return iterator(nullptr);
		}
		iterator ret(p->next);
		iterator pre_it = findPre(p->data);
		if (pre_it.current->next != nullptr) {
			pre_it.current->next = p->next;
		}
		delete p;
		theSize--;
		return ret;
	}
	iterator erase(iterator from, iterator to) {
		iterator it(from);
		for (; it != to;) {
			it = erase(it);
		}
		return it;
	}

	void pop_front() {
		erase(begin());
	}

	void push_front(const Object & X) {
		insert(iterator(head), X);
	}

	void reverse(LinkList &L) {
		if (empty()) return;
		Node * pre = nullptr;
		Node * cur = L.head->next;
		while (cur != nullptr) {
			Node * tmp = cur->next;
			cur->next = pre;
			pre = cur;
			cur = tmp;
		}
		L.head->next = pre;
	}

private:
	int theSize;
	Node * head;

	void init() 
	{
		theSize = 0;
		head = new Node;
	}
};

int main(int argc, char **argv)
{
	{
		LinkList<int> L;
		LinkList<int>::iterator it;

		try {
			L.push_front(1);
			L.push_front(2);
			L.push_front(3);
			L.push_front(3);
			L.push_front(3);
			L.push_front(4);
			L.push_front(5);
			L.push_front(7);
			L.deleteEle(7);
			L.deleteEle(700);
			it = L.find(5);
			if (it != L.end()) {
				std::cout << "find " << *it << std::endl;
			}
			else {
				std::cout << "Don't find\n";
			}
			L.reverse(L);
	
			std::cout << "\nsize is " << L.size() << std::endl;
			for (it = L.begin(); it != L.end();) {
				std::cout << *it << " ";
				if (3 == *it) {
					it = L.erase(it);
				}
				else {
					it++;
				}
			}
			std::cout << std::endl;

			std::cout << "\nsize is " << L.size() << std::endl;
			for (LinkList<int>::const_iterator con_it = L.begin(); con_it != L.end(); con_it++) {
				std::cout << *con_it << " ";
			}
			std::cout << std::endl;

			L.pop_front();
			std::cout << "\nsize is " << L.size() << std::endl;
			for (LinkList<int>::const_iterator con_it = L.begin(); con_it != L.end(); con_it++) {
				std::cout << *con_it << " ";
			}
			std::cout << std::endl;

			L.erase(++L.begin(), L.end());
			std::cout << "\nsize is " << L.size() << std::endl;

			L.clear();
			std::cout << "\nsize is " << L.size() << std::endl;
		}
		catch (std::runtime_error &e) {
			std::cerr << e.what() << std::endl;
		}
	}

	return 0;
}

参考文献

数据结构与算法分析第三版(C++)

你可能感兴趣的:(数据结构与算法)