slist双向链表容器
一、原理
slist为单向链表的泛化容器,与list双向链表容器一样,实现了线性表数据的链表存储,元素数据不必在物理内存中连续分布。slist链表的节点,只有后继的指针,不含前驱的指针。slist为SGI C++ STL自设的一个容器,在Visual C++自带的P.J.Plauger STL中并不存在。STLport源自于SGI C++ STL,但可适用于多种主流编译平台。
二、应用
1、创建
(1)slist()
创建一个不存在任何元素的slist对象。它是slist(const A& a = A())的一个默认调用形式,其中A为内存分配器。
slist<int> sl;
(2)slist(size_type n)
创建一个链接有n个元素的slist对象,每个元素数据采用默认类型值。
slist<int> sl(10);//每个元素初始值为0。
(3)slist(size_type n, const T& value)
创建一个链入了 n 个元素的 slist 对象,这些元素的初始值均为 value。
slist<double> sl(10, 2.3);//每个元素的初始值为2.3
(4)slist(const slist&)
通过拷贝一个slist对象的元素值,创建一个新的slist对象。新创建的list对象元素与原有的slist对象元素对应相等。
slist<char> sl1(5, ’k’);
slist<char> sl2(sl1);//sl2对象的5个元素也具有字符值’k’。
(5)slist(InputIterator first, InputIterator last)
拷贝一个slist对象的迭代器区间[first, last]所指的元素值,生成另一个新的slist对象。它实际是slist(const InputIterator first, const InputIterator last, const A& a=A())构造函数的一个省略写法。
int iArray[] = {19, 13, 38};
slist<int> sl(iArray, iArray + 3);
2、插入
1)由于slist的头节点仅有一个指针域保存单向链表的首元素地址,而没有存放最后一个元素的地址,所以用push_front函数在链表首元素前面,插入一个新元素,使之成为首元素,它的使用原型如下。
void push_front(const T&)
而没有push_back函数。
2)对于任意位置上的 slist 链表元素的插入,可使用 insert_after 和 insert 函数。insert_after函数直接在指定的 pos 位置之后插入新元素。insert 函数则从单向链表的头节点开始,找到pos的前驱位置,然后调用insert_after函数进行插入,因此执行效率较低。它们较常用的使用原型如下。
(1)iterator insert_after(iterator pos, const T& x)
(2)iterator insert(iterator pos, const T& x)
3、访问
1)迭代器
(1)iterator begin(
(2)iterator end()//end函数的返回迭代器,在slist链表结构中实际是不存在的,只是纯粹的代码构造
//头节点的后继节点为第个元素
iterator begin() { return iterator((Node*)this->M_head.M_next); }
//构造一个M_node为null指针的迭代器作为end()的返回
//直观地说,相当于最后一个节点的null指针所指向的节点位置为end迭代器
iterator end() { return iterator(0); }
4、其它
其它,比如删除,交换,排序,归并,重复元素的剔除,函数形式同list.
三、例子
#include <slist>
#include <iostream>
int main(void){
using namespace std;
slist<int> sl; //在链表尾进行插入
slist<int>::iterator iLast=sl.previous(sl.end());//前驱,最后一个元素
iLast = sl.insert_after(iLast, 61);
iLast = sl.insert_after(iLast, 62);
iLast = sl.insert_after(iLast, 63);
iLast = sl.insert_after(iLast, 64);
iLast = sl.insert_after(iLast, 65);
//从头到尾打印链表元素
slist<int>::iterator i;
for(i=sl.begin(); i!=sl.end(); i++)//打印62 63 64 65
cout << *i << ’’;
cout << endl;
return 0;
}
//相当于一个“--”操作,返回pos的前一个位置,但需要从头节点开始一个一个元素遍历
iterator previous(const_iterator pos) {
return iterator((Node*) slist_previous(&this->M_head, pos.M_node));
}
在www.stlport.org上下载STLport-4.6.2.tar.gz,编译方可使用
Nmake -f vc6.mak clean all //假设在VC++下使用,并且在include file中添加