码迷,mamicode.com
首页 > 其他好文 > 详细

双向链表(插入,删除,追加,正反向遍历,查找。。。)

时间:2014-09-14 19:21:27      阅读:230      评论:0      收藏:0      [点我收藏+]

标签:链表   遍历   exception   class   

#include <iostream>
#include <stdexcept>
using namespace std;
class List
{
public:
	List(void) : m_head(NULL), m_tail(NULL), m_size(0){}
	~List(void)
	{
		for(Node* node = m_head; m_head; m_head = node)
		{
			node = m_head->m_next;
			delete m_head;
		}
	}
	//在Index处插入元素
	void insert(int data, size_t index)
	{
		//如果下标超过元素个数,则追加在链表最后
		if(index >= m_size)
		{
			append(data);
			return;
		}
		Node* temp = new Node(data);
		//如果下标为0,则插入在头节点
		if(0 == index)
		{
			temp->m_next = m_head;
			m_head->m_prev = temp;
			m_head = temp;
			++m_size;
			return;
		}
		size_t count = 1;
		//其它情况
		for(Node* node = m_head->m_next; node; node = node->m_next)
		{
			if(index == count)
			{
				temp->m_next = node;
				temp->m_prev = node->m_prev;
				node->m_prev->m_next = temp;
				node->m_prev = temp;
				++m_size;
				return;
			}
			++count;
		}
	}
	//在链表尾部追加元素
	void append(int data)
	{
		Node* node = new Node(data);
		if(!m_head)
			m_head = node;
		else
		{
			node->m_prev = m_tail;
			m_tail->m_next = node;
		}
		m_tail = node;
		++m_size;
	}
	//删除元素
	void erase(size_t index)
	{
		if(!m_head)
			throw UnderFlow();
		//首先查找要删除的元素
		Node*& node = find(index, m_head);
		node->m_prev->m_next = node->m_next;
		node->m_next->m_prev = node->m_prev;
		delete node;
		node = NULL;
	}
	//查找元素
	int& find(size_t index)
	{
		Node*& node = find(index, m_head);
		return node->m_data;
	}
	//正向遍历
	void forward ()const
	{
		if(!m_head)
			throw UnderFlow();
		for(Node* node = m_head; node; node = node->m_next)
		{
			cout << node->m_data << ' ';
		}
		cout << endl;
	}
	//反向遍历
	void backward()const
	{
		if(!m_tail)
			throw UnderFlow();
		for(Node* node = m_tail; node; node = node->m_prev)
		{
			cout << node->m_data << ' ';
		}
		cout << endl;
	}
	//链表元素个数
	size_t size()
	{
		return m_size;
	}
	//重载下标操作符,作为左值
	int& operator[] (size_t index)
	{
		if(index >= m_size)
			throw OverFlow();
		Node*& node = find(index, m_head);
		return node->m_data;
	}
	//重载下标操作符,作为右值
	const int& operator[] (size_t index)const
	{
		//去常属性后,调用上面下标重载
		return const_cast<List&>(*this) [index];
	}
private:
	//链表每个节点
	class Node
	{
	public:
		Node(int data=0, Node* prev=NULL, Node* next=NULL):
			m_data(data), m_prev(prev), m_next(next){}
		int m_data;
		Node* m_prev;
		Node* m_next;
	};
	//下溢异常类
	class UnderFlow : public exception
	{
	public:
		const char* what() throw()
		{
			return "下溢异常!";
		}
	};
	//下标越界!
	class OverFlow : public exception
	{
	public:
		const char* what() throw()
		{
			return "下标越界!";
		}
	};
	Node*& find(size_t index, Node* head)
	{
		if(index >= m_size)
			throw OverFlow();
		size_t count = 0;
		for(Node*& node = head; node; node = node->m_next)
		{
			if(index == count)
				return node;
			++count;
		}
	}
	Node* m_head;
	Node* m_tail;
	size_t m_size;
};
int main()
{
	List list;
	list.append(10);
	list.append(20);
	list.append(30);
	list.append(40);
	list.append(50);
	list.append(60);
	list.append(70);
	cout << "元素个数:" << list.size() << endl;
	list.forward();
	list.backward();
	list.insert(100, 0);
	list.insert(150, 11);
	cout << "元素个数:" << list.size() << endl;
	list.forward();
	list.backward();
	cout << "第5个元素是:" << list.find(5) << endl;
	list.erase(5);
	cout << "删除第5个元素后:";
	list.forward();
	list[5] = 876;
	list.forward();
	cout << "第5个元素是:" << list[5] << endl;
	return 0;
}

双向链表(插入,删除,追加,正反向遍历,查找。。。)

标签:链表   遍历   exception   class   

原文地址:http://blog.csdn.net/liyuan_669/article/details/39271845

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!