STL中双向链表的简单实现

整体构架

将list链表的实现分为层结构:

第一层:用于保存元素数值及前后元素地址的结构体,定名为Node

struct Node
	{
		Object data;   //保存数值
		Node *prev;    //保存前导地址;
		Node *next;    //保存后继地址;
	};


 

第二层:定义用于定位的迭代器。迭代器保存Node类型的地址,从未为上层函数提供确定元素位置的功能,实际上就是一个Node结构体的指针。

//定义套嵌的迭代器类
	class iteractor
	{
	public:
		//重载迭代器的构造函数
		iteractor(Node *p):current(p){};

        //返回指向的数据值;
		Object retieve() const
		{
			return current->data;
		}
		
		//重载自加运算符(前缀的自加运算
		iteractor  operator++ ()
		{
			Node *Oldcurrent=current->next;
			current=Oldcurrent;     //自加操作后迭代器指向下一个元素
			return iteractor(current);
		}

		//重载后缀的自加操作符
		/*(iteractor & operator++(int)
		{

		}*/

		//重载“==”预算符号
		bool operator ==(iteractor &itr) 
		{
			return current==itr.current;
		}

		//重载“!=”预算符号
		bool operator !=(iteractor &itr) const
		{
			return current!=itr.current;
		}

public:
		Node *current;     //迭代器为Node类型的地址
		
	};


 

public:
		Node *current;     //迭代器为Node类型的地址
		
	};


 

 

第三层:基础的功能函数,包括访问函数

判断是否为空的Empty();

template<class Object>
bool List<Object>::Empty()
{
	if(theSize==0)
		return 1;
	else
		return 0;
}


 

返回链表中的元素个数的theSize()

template<class Object>
int List<Object>::Size()
{
	return theSize;
}

返回头元素的地址的begin();

//返回链表头部的地址迭代器
	iteractor begin()           
	{
		return iteractor(head->next);
	}


 

返回尾元素地址的end();

/返回链表尾部的地址迭代器
	iteractor end()             
	{
		return iteractor(tail);
	}


 

以及操作函数:

插入元素insert()

//在指定位置插入相应的数值
	iteractor insert(iteractor itr,Object x)      //
	{
		Node *p=new Node;          //为新元素创建分配一块内存
		p->data=x;                 //新元素的数值赋值
		p->prev=itr.current->prev; //新元素前导地址为1;
		p->next=itr.current;       //新元素后继地址
		itr.current->prev->next=p; //
		itr.current->prev=p;       //
		theSize++;
		return iteractor(p);

	}


 

删除元素erase()

//在指定的位置删除元素
	void erase(iteractor itr)       //
	{
		itr.current->next->prev=itr.current->prev;
		itr.current->prev->next=itr.current->next;
	}

以上这些第三层的函数,都是为第四层的对表的操作的高级函数进行具体执行工作的;

 

第四层 这一层主要执行对表的操作

 

在表头插入元素push_front

//在头部插入元素
	void push_front(Object x) 
	{
		insert(begin(),x);
	}


 

在表头删除元素pop_fronr

//在头部弹出元素
	void pop_front()   
	{
		erase(begin());
	}


 

在表的末尾插入元素push_end

//在尾部插入元素
	void push_end(Object x)
	{
		insert(end(),x);
	}


 

在表尾弹出元素pop_end

//在尾部弹出元素
	void pop_end()    
	{
		erase(iteractor(end().current->prev));
	}

 

注意事项

1、由于链表只是一个保存不同数据类型数据的一种容器形式,因此保存在list中的数据可能是各种类型的数据,为了适应各种的数据类型,将list类设置为类模板

template<typename Object>
class List
{


 

2、由于list是一个模板类,因此list类的成员函数最好在类内部进行声明和定义,因为若在外部定义其定义表述极其的繁琐,如下面empty这个函数

template<class Object>
bool List<Object>::Empty()
{
	if(theSize==0)
		return 1;
	else
		return 0;
}


 

3、迭代器(iterator)是一个套嵌在list类中的新的类型,需要在list类中进行定义。其本质是保存Node结构体的地址,其主体是其数据成员current。


 

public:
		Node *current;     //迭代器为Node类型的地址


 

4、list链表的数据成员包括了元素个数(theSize)、头元素(head)、尾元素(tail)。其中头元素和尾元素只是作为标志位,用于定位链表的开头和结尾的位置,不计入链表的元素个数,这从list的构造函数中就能够看出

List()
	{
		theSize=0;
		head=new Node;
		tail=new Node;
		head->next=tail;
		tail->prev=head;
		tail->next=NULL;
	}


 

5、在函数begin返回函数头是,迭代器存的并不是head的地址,而是head后面的元素的地址

 

 

 

而end函数返回的指针则是指向tail元素自己

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值