链表(下) DualLinkList、DualCircleList

DualLinkList

  双向链表的由来:单链表只可以向后访问,如果要逆序访问,效率将会很低

  双向链表的特点:
    比单链表多了前驱,可以逆序访问
    提供游标与步长,使用方式与单链表相同
    
DualLinkList.h

#ifndef _DualLinkList_H_
#define _DualLinkList_H_
#include "include/LinuxList.h"
#include "include/Exception.h"

namespace JYlib
{

/*				双向链表
功能:
*/
template < typename T >
class DualLinkList:public List<T>
{
protected:
#pragma pack(4)
	struct Node : public Object
	{
		T value;
		Node* next;
		Node* pre;
	};
	/*
		不直接使用Node*声明(使用sizeof),是为了避开泛指类型T的构造,因为T的构造可能会发生异常
		都继承自顶层父类,保证内存布局与node相同,就可以通过retinterpret_cast强制转换来使用
		mutable的声明是因为const成员函数中会取m_header的地址
	*/
	mutable struct : public Object
	{
		char reserved[sizeof(T)];
		Node* next;
		Node* pre;
	}m_header; 
#pragma pack()
	
	int m_length;


	Node* m_current;//游标当前位置
	int m_step;//游标步进的长度

	//定位对象的前一个位置
	Node* position(int i)const
	{
		Node* ret = reinterpret_cast<Node*>(&m_header);

		for(int j = 0;j < i;j++)
		{
			ret = ret->next;
		}
		return ret;
	}

	//封装申请与删除 增强拓展性
	virtual Node* create()
	{
		return new Node();
	}

	virtual void destroy(Node* pn)
	{
		delete pn;
	}
public:
	DualLinkList()
	{
		m_header.pre = NULL;
		m_header.next = NULL;
		m_current = NULL;
		m_step = 1;
		m_length = 0;
	}

    DualLinkList(const List<T>& t);

    DualLinkList& operator =(const List<T>& e);

	bool insert(const T& e)
	{
		return insert(m_length,e);
	}

	bool insert(int i,const T& e)
	{
		bool ret = (0 <= i)&&(i <= m_length);//小于等于是为了可以在末尾插入
		if(ret)
		{
			Node* new_Node = create();

			if(new_Node != NULL)
			{
				Node* current = position(i);
				Node* next = current->next;

				new_Node->value = e;
				
				current->next = new_Node;
				new_Node->next = next;

				if(current != reinterpret_cast<Node*>(&m_header))//如果不是首结点
				{
					new_Node->pre = current;
				}
				else
				{
					new_Node->pre = NULL;
				}
				if(next != NULL)//下一个节点是否使用
				{
					next->pre = new_Node;
				}

				m_length++;
			}
			else
			{
				THROW_EXCEPTION(NoEnoughMemoryException,"No memory to create DynamicList object ...");
			}
		}
		return ret;
	}

	bool remove(int i)
	{
		bool ret = ((0 <= i)&&(i < m_length));
		if(ret)
		{
			Node* current = position(i);
			Node* remove = current->next;
			Node* next = remove->next;

			if(m_current == remove)//如果当前游标在此,则游标指向下一个位置
			{
				m_current = next;
			}
			current->next = next;
			if(next != NULL)
			{
				if(current == reinterpret_cast<Node*>(&m_header))//如果是首结点,前一个节点为空
				{
					next->pre = NULL;
				}
				else
				{
					next->pre = current;
				}
			}
			
			m_length--;
			destroy(remove);//先改数据,后析构,即使析构出问题,其仍然已经不是单链表一员
		}
		return ret;
	}

	bool set(int i,const T& e)
	{
		bool ret = (0 <= i)&&(i < m_length);
		if(ret)
		{
			position(i)->next->value = e;
		}
		else
		{
			THROW_EXCEPTION(IndexOutOfBoundsException,"Parameter i is invalid ...");//抛出数组越界异常
		}
		return ret;
	}

	bool get(int i,T& e)const
	{
		bool ret = (0 <= i)&&(i < m_length);
		if(ret)
		{
			e = position(i)->next->value;
		}
		else
		{
			THROW_EXCEPTION(IndexOutOfBoundsException,"Parameter i is invalid ...");//抛出数组越界异常
		}
		return ret;
	}
	
	virtual T get(int i)const
	{
		T ret;

		get(i,ret);

		return ret;
	}

	int find(const T& e)const
	{
		int ret = -1;
		int i = 0;
		Node* node = m_header.next;
		
		while(node != NULL)
		{
			if(node->value == e)
			{
				ret = i;
				break;
			}
			else
			{
				node = node->next;
				i++;
			}
		}
		return ret;
	}

	int length(void)const
	{
		return m_length;
	}

	//游标移动到目的地址,并重设置步进值
	virtual bool move(int i,int step = 1)
	{
		bool ret = (0 <= i)&&(i < m_length)&&(step > 0);
		if(ret)
		{
			m_current = position(i)->next;
			m_step = step;
		}
		else
		{
			THROW_EXCEPTION(IndexOutOfBoundsException,"Parameter i is invalid ...");//抛出数组越界异常
		}

		return ret;
	}

	//游标是否到末尾
	virtual bool end()
	{
		return (m_current == NULL);
	}

	//当前游标的值
	virtual T current()
	{
		if(!end())
		{
			return m_current->value;
		}
		else
		{
			THROW_EXCEPTION(IndexOutOfBoundsException,"Parameter i is invalid ...");//抛出数组越界异常
		}
	}
	
	//步进至一个游标
	virtual bool next()
	{
		int i = 0;
		while((i < m_step)&&(!end()))
		{
			m_current = m_current->next;
			i++;
		}
		return (i == m_step);
	}

	virtual bool pre()
	{
		int i = 0;
		while((i < m_step)&&!end())
		{
			m_current = m_current->pre;
			i++;
		}
		return (i == m_step);
	}

	void clear()
	{
		while(m_length > 0)
		{
			remove(0);
		}
	}

	~DualLinkList()
	{
		clear();
	}
};

}


#endif

DualCircleList


  通过Linux内核链表实现:

DualCircleList_Linux.h

#ifndef _DualCircleLinkList_Linux_H_
#define _DualCircleLinkList_Linux_H_
#include "include/DualLinkList.h"
#include "include/LinuxList.h"

namespace JYlib
{

/*				双向循环链表
功能:增删查改  前序与后序遍历
*/
template < typename T>
class DualCircleList_Linux:public DualLinkList<T>
{
protected:
	struct Node:public Object
	{
		list_head head;//双指针结构体
		T value;
	};

	list_head m_header;
	list_head* m_current;

	list_head* position(int i)const
	{
		list_head* ret = const_cast<list_head*>(&m_header);

		for(int p=0;p<i;p++)
		{
			ret = ret->next;
		}
		return ret;
	}

	int mod(int i)const
	{
		return (this->m_length == 0 ? 0 : i%(this->m_length));
	}
public:
    DualCircleList_Linux():DualLinkList<T>()
	{
		m_current = NULL;
		INIT_LIST_HEAD(&m_header);
	}

	bool insert(const T& e)
	{
		return insert(this->m_length,e);
	}

	bool insert(int i,const T& e)
	{
		bool ret = true;
		i = i % (this->m_length + 1);

		Node* new_node = new Node();
		if(new_node != NULL)
		{
			new_node->value = e;

			list_add_tail(&new_node->head,position(i)->next);
			this->m_length++;
		}
		else
		{
			THROW_EXCEPTION(NoEnoughMemoryException,"No memory to insert new element ...");
		}
		return ret;
	}

	bool remove(int i)
	{
		i = mod(i);
		bool ret =(0 <= i)&&(i < this->m_length);

		if(ret)
		{
			list_head* remove = position(i)->next;
			if(m_current == remove)
			{
				m_current = m_current->next;
			}
		
			list_del(remove);

			this->m_length--;

			delete list_entry(remove,Node,head);
		}
		
		return ret;
	}

	T get(int i)const
	{
		T ret;

		get(i,ret);

		return ret;
	}

	bool get(int i,T& e)const
	{
		i = mod(i);
		bool ret = ( (0 <= i)&&(i < this->m_length) );

		if(ret)
		{
			e = list_entry(position(i)->next,Node,head)->value;
		}

		return ret;
	}

	bool set(int i,const T& e)
	{
		i = mod(i);
		bool ret = ( (0 <= i)&&(i < this->m_length) );

		if(ret)
		{
			list_entry(position(i)->next,Node,head)->value = e;
		}

		return ret;
	}

	int find(const T& e)const
	{
		int ret = -1;

		int i = 0;

		list_head* silder = NULL;

		list_for_each(silder,&m_header)
		{
			if(list_entry(silder,Node,head)->value == e)
			{
				ret = i;
				break;
			}
			i++;
		}
		return ret;
	}

	bool move(int i,int step = 1)
	{
		bool ret = (step > 0);

		i = mod(i);

		ret = ret && (0 <= i) && (i < this->m_length);

		if(ret)
		{
			m_current = position(i)->next;

			this->m_step = step;
		}
		return ret;
	}

	bool end()
	{
        return (m_current == NULL || this->m_length == 0);
	}

	//当前游标的值
	T current()
	{
		if(!end())
		{
			return list_entry(m_current,Node,head)->value;
		}
		else
		{
			THROW_EXCEPTION(IndexOutOfBoundsException,"Parameter i is invalid ...");//抛出数组越界异常
		}
	}
	
	//步进至一个游标
	bool next()
	{
		int i = 0;
		while((i < this->m_step)&&!end())
		{
			if(m_current != &m_header)
			{
				m_current = m_current->next;
				i++;
			}
			else
			{
				m_current = m_current->next;
			}
		}
		if(m_current == &m_header)
		{
			m_current = m_current->next;
			i++;
		}
		return (i == this->m_step);
	}

	bool pre()
	{
		int i = 0;
		while((i < this->m_step)&&!end())
		{
			if(m_current != &m_header)
			{
				m_current = m_current->prev;
				i++;
			}
			else
			{
				m_current = m_current->prev;
			}
		}
		if(m_current == &m_header)
		{
			m_current = m_current->prev;
			i++;
		}

		return (i == this->m_step);
	}

	void clear()
	{
		while(this->m_length > 0)
		{
			remove(0);
		}
	}

	~DualCircleList_Linux()
	{
		clear();
	}
};

}


#endif


  通过双向链表以及循环链表实现:
DualCircleList.h

#ifndef _DualCircleLinkList_H_
#define _DualCircleLinkList_H_
#include "include/DualLinkList.h"

namespace JYlib
{

template < typename T>
class DualCircleList:public DualLinkList<T>
{
protected:
    typedef typename DualCircleList<T>::Node Node;

	int mod(int i)const
	{
		return (this->m_length == 0 ? 0 : i%(this->m_length));
	}

	Node* last()
	{
		return (this->position(this->m_length));
	}

	void last_to_first()
	{
		Node* m_last = last();
		this->m_header.next->pre = m_last;
		m_last->next = this->m_header.next;
	}
    
public:
    DualCircleList():DualLinkList<T>()
	{

	}

	bool insert(const T& e)
	{
        return insert(this->m_length,e);
	}

	bool insert(int i,const T& e)
	{
		bool ret = DualLinkList<T>::insert(i,e);
		i = i % (this->m_length + 1);

		if(ret && (i == 0))
		{
			last_to_first();
		}
		
		return ret;
	}

	bool remove(int i)
	{
		bool ret = false;
		i = mod(i);
		
		if(i == 0)//删除的是头结点
		{
			Node* remove = this->m_header.next;
			Node* next = remove->next;
			if(remove == NULL)
			{
				return false;
			}
			else
			{
				this->m_length--;
				this->m_header.next	= next;

				if(next == NULL)//除首结点外无节点
				{
					this->m_header.next = NULL;
					this->m_header.pre = NULL;
					this->m_current = NULL;
				}
				else//除首结点外有节点
				{
					if(this->m_current == remove)
					{
						this->m_current = this->m_current->next;
					}
					last_to_first();
				}
				this->destroy(remove);
				ret = true;
			}
		}
		else//删除非头结点
		{
			ret = DualLinkList<T>::remove(i);
		}
		return ret;
	}

	T get(int i)const
	{
		return DualLinkList<T>::get(mod(i));
	}

	bool get(int i,const T& e)const
	{
		return DualLinkList<T>::get(mod(i),e);
	}

	bool set(int i,const T& e)
	{
		return DualLinkList<T>::set(mod(i),e);
	}

	int find(const T& e)const
	{
		int ret = -1;

		Node* silder = this->m_header.next;

		for(int i=0;i<this->m_length;i++)
		{
			if(silder->value == e)
			{
				ret = i;
				break;
			}
			silder = silder->next;
		}

		return ret;
	}

	void clear()
	{
		if(this->m_length > 0)
		{
			while(this->m_length > 1)
			{
				remove(1);
			}
			if(this->m_length == 1)
			{
				Node* remove = this->m_header.next;

				this->m_header.next = NULL;
				this->m_header.pre = NULL;
				this->m_current = NULL;
				this->m_length = 0;

				this->destroy(remove);
			}
		}
	}

	bool move(int i,int step = 1)
	{
		return DualLinkList<T>::move(mod(i),step);
	}

	bool end()
	{
		return (this->m_length == 0)||(this->m_current == NULL); 
	}

	~DualCircleList()
	{
		clear();
	}
};

}


#endif

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值