您的位置:首页 > 其它

STL中双向链表的简单实现

2013-07-10 14:15 549 查看
整体构架

将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元素自己



 

 

 

 

 

 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: