自己动手写数据结构:双向循环List类模板C++实现(功能较全)

       双向循环链表的概念想必大家应该比我清楚呵,在此不多说,主要想总结一下我在编程过程中的两点经验:

       第一,如果在链表中插入时仅仅指出直接前驱结点,钩链时必须注意先后次序是: “先右后左”。部分语句组如下:

L= new LNode();
L->val=e;
L->next=p->next;   p->next->prev=L;
p->next=L;         L->prev=p;    /*  钩链次序非常重要  */

        而如果插入时同时指出直接前驱结点p和直接后继结点q,钩链时无须注意先后次序。部分语句组如下:

L= new LNode();
L->val=e;
p->next=S;   L->next=q;
L->prev=p;   q->prev=L;

        第二,若List类中有成员函数返回的是在List类中定义的LIterator类型,那么必须在返回类型前加上typename,否则会出现编译错误:“error C4430: 缺少类型说明符”,这主要是因为LIterator有可能是类的数据成员或static成员,因此编译器不会默认为是类类型。部分语句组如下:

template <class T>
typename MyList<T>::LIterator MyList<T>::insert(LIterator& it, const T& t)
{
 LNode* temp = it.node->prev;
 temp = temp->next = new LNode(t, temp, it.node);
 it.node = it.node->prev;

 ++_size;
 LIterator LIter(temp);
 return LIter;
}

源代码如下:<MyList.h>

template <class T>
class MyList
{
protected:
	class LNode
	{
	public:
		LNode(const T& t = T(), LNode* p = 0, LNode* n = 0):val(t), prev(p), next(n) 
		{
			if (prev == 0) prev = this;
			if (next == 0) next = this;
		}
		T val;
		LNode* prev, *next;		
	};
public:
	class LIterator
	{
	public:
		friend class MyList<T>;
		LIterator() {}
		LIterator(LNode* n) : node(n){}
		LIterator(const LIterator& L) : node(L.node) {}
		~LIterator() {}
		T& operator * () {return node->val;}
		LIterator& operator = (const LIterator& it) {node = it.node;}
		bool operator == (const LIterator& it) {return it.node == node;}
		bool operator != (const LIterator& it) {return it.node != node;}
		LIterator operator ++ (int) // 后缀iter++
		{
			LIterator it(node);
			node = node->next;
			return it;
		}
		LIterator& operator ++ () // 前缀++iter
		{
			node = node->next;
			return *this;
		}
		LIterator operator -- (int)
		{
			LIterator it(node);
			node = node->prev;
			return it;
		}
		LIterator& operator -- ()
		{
			node = node->prev;
			return *this;
		}
	protected:
	private:
		LNode* node;
	};

	MyList();
	MyList(const MyList& L);
	MyList(int n);
	MyList(int n, const T& t);
	MyList(LIterator& first, LIterator& last);
	~MyList();
	MyList& operator = (const MyList& L);

	int getSize() const {return _size;}
	bool empty() const {return _size == 0;}
	T& front();
	T& back();

	LIterator begin();
	LIterator end(); //返回虚拟头指针,不指向任何有效元素
	void push_front(const T& t);
	void push_back(const T& t);
	void pop_front();
	void pop_back();

	LIterator insert(LIterator& it, const T& t);
	LIterator insert(LIterator& it, int n, const T& t);

	void erase(LIterator& it);
	void erase(LIterator& first, LIterator& last);
	void clear();
	void splice(LIterator& it, MyList& list, LIterator& first);
private:
	LNode* _head; //虚拟头指针
	size_t _size;
};

template <class T> MyList<T>::MyList():_size(0)
{
	_head = new LNode;
}

template <class T> MyList<T>::MyList(const MyList& list):_size(list._size)
{
	_head = new LNode();
	LNode* temp = _head;
	for (LNode* p = list._head->next; p != list._head; p = p->next)
	{
		temp = temp->next = new LNode(p->val, temp, _head);
	}
	_head->prev = temp;
}

template <class T> MyList<T>::MyList(int n):_size(n)
{
	_head = new LNode;
	LNode* temp = _head;
	for (int i = 0; i < n; i ++)
	{
		temp = temp->next = new LNode(T(), temp, _head);
	}
}

template <class T> MyList<T>::MyList(int n, const T& t):_size(n)
{
	_head = new LNode();
	LNode* temp = _head;
	for (int i = 0; i < n; i ++)
	{
		temp = temp->next = new LNode(t, temp, _head); //往temp和head中间插入新节点
	}
	_head->prev = temp;
}

template <class T> MyList<T>::MyList(LIterator& first, LIterator& last)
{
	_head = new LNode;
	LNode* temp = _head;
	for (LIterator p = first; first != last; last ++)
	{
		temp = temp->next = new LNode(p.node->val, temp, _head);
		++_size;
	}
}

template <class T> MyList<T>::~MyList()
{
	LNode* temp = _head->next;
	while (temp != _head)
	{
		LNode* p = temp;
		temp = temp->next;
		delete p;
	}
	delete _head;
}

template <class T> MyList<T>& MyList<T>::operator = (const MyList& L) : _size(L._size)
{
	clear();
	_head = new LNode;
	LNode* temp = _head;
	LNode* p = L._head->next;
	while (p != L._head)
	{
		temp = temp->next = new LNode(p->val, temp, _head);
		p = p->next;
	}
}

template <class T> T& MyList<T>::front()
{
	return _head->next->val;
}

template <class T> T& MyList<T>::back()
{
	return _head->prev->val;
}

template <class T> typename MyList<T>::LIterator MyList<T>::begin() //注意:这里必须加typename,否则VC无法编译通过!
{
	LIterator temp(_head->next);
	return temp;
}

template <class T> typename MyList<T>::LIterator MyList<T>::end()
{
	LIterator temp(_head);
	return temp;
}

template <class T> void MyList<T>::push_front(const T& t)
{
	_head->next = _head->next->prev = new LNode(t, _head, _head->next);
	++_size;
}

template <class T> void MyList<T>::push_back(const T& t)
{
	LNode* temp = _head->prev;
	temp = temp->next = new LNode(t, temp, _head); //这里往temp和head中间插入新节点,也可以相反
    _head->prev = temp;
	++_size;
}

template <class T> void MyList<T>::pop_front()
{
	if (_size > 0)
	{
		LNode* temp = _head->next;
		_head->next = temp->next;
		temp->next->prev = _head;
		delete temp;
		--_size;
	}
	return ;
}

template <class T> void MyList<T>::pop_back()
{
	if (_size > 0)
	{
		LNode* temp = _head->prev;
		_head->prev = temp->prev;
		temp->prev->next = _head;
		delete temp;
		--_size;
	}
	return ;
}

template <class T> 
typename MyList<T>::LIterator MyList<T>::insert(LIterator& it, const T& t) //在it前插入元素
{
	LNode* temp = it.node->prev;
	temp = temp->next = new LNode(t, temp, it.node);
	it.node = it.node->prev;

	++_size;
	LIterator LIter(temp);
	return LIter;
}

template <class T> 
typename MyList<T>::LIterator MyList<T>::insert(LIterator& it, int n, const T& t)
{
	LNode* p = it.node;
	LNode* q = p->prev;
	for (int i = 0; i < n; i ++)
	{
		q = q->next = new LNode(t, q, p);
		++_size;
	}
	p->prev = q;
	it.node = p;

	LIterator LIter(p);
	return LIter;
}

template <class T> 
void  MyList<T>::erase(LIterator& it)
{
	if (_size == 0) return;
	LNode* temp = it.node;
	temp->prev->next = temp->next;
	temp->next->prev = temp->prev;
	it.node = temp->next;
	delete temp;
	--_size;
}

template <class T> 
void MyList<T>::erase(LIterator& first, LIterator& last) //last不会被删除
{
	first.node->prev->next = last.node;
	last.node->prev = first.node->prev;

	LNode* temp = first.node;
	LNode* p = first.node->next;
	while (temp != last.node)
	{
		delete temp;
		temp = p;
		p = p->next;		
		--_size;
	}
}

template <class T> 
void MyList<T>::clear()
{
	while (_head->next != _head)
	{
		pop_back();
	}
}

template <class T> 
void MyList<T>::splice(LIterator& it, MyList& L, LIterator& first) //从其他list中抽取元素first至it前
{
	LNode* p = it.node;
	LNode* q = first.node;

	q->prev->next = q->next; //先将first断开
	q->next->prev = q->prev;

	q->prev = p; //再将first与it连接,原则:先右后左
	q->next = p->next;

	p->next->prev = q;
	p->next = q;

	++_size;
	--L._size;	
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值