第六章 表容器和迭代器

6.1 表容器

表容器是按位置保存元素的数据结构。然而,与向量不同的是,她不提供直接按位置访问元素的外部索引机制。而且,表中的每个元素包含指明序列中下一个和上一个元素的链接。这些项列成一行,从第一个元素(称为表头)开始,按连续次序到最后一个元素(称为表尾)。

定位元素的过程采用顺序扫描的方式,从表头开始,逐项朝前移动,直到指定的元素。类似的扫描从表尾开始,想表头移动,直到出现匹配项。

6.1.1 表ADT

此类用3个构造函数声明表对象。构造函数形式和向量类使用的相同。默认的构造函数生成一个空表,其他两个版本分配带有初始值的表对象:一个版本用大小n和类型T的一个数值作为参数,并生成n个元素的一个表,所有元素都被设定为指定值;另一个版本用不同的值初始化对象。程序员先声明带有这些值的数组,然后把数组的地址范围作为参数传递进来。

所有的STL容器都有一组共同的成员函数。复制构造函数,析构函数和重载赋值运算符提供了运行时的内存管理工具。每个容器对象也有size()和empty()函数。

list类提供了一组允许程序员在序列两端增加或删除元素的操作,还提供了在中间位置对数据项进行一般的插入和删除操作。连续调用push_front()按反序增加元素;连续调用push_back()按正序增加元素。

6.1.2 表API

list();生成一个空表。这是默认构造函数。

list(int n, const T& Value = T());生成n个元素的表,每个元素有一个指定的值。

list(T* first , T*last); 用地址范围初始化表

T& back();返回表尾数据项的值

bool empty() const ; 如果表空 ,TRUE

T&  front() ; 返回表首项的值

void  push_back(const T&  Value);在表尾增加一个值

void  pop_back();一走表尾项。

void push_front(const T& Value) ;在表头增加一个新值

void pop_front() ; 一走表头的值。

int size() const  ; 返回表中的元素个数。

 

6.2 迭代器

向量可以用下标访问序列中的每个元素。表没有这样的工具。除了front 和back 之外,我们没有办法识别表中的其他元素。然而,表中的项包含指示序列中上一项和下一项的指针。这些指针可以从front和back两个方向扫描表。到目前为止,我们没有讲述利用元素的指针属性的方法,因此不能扫描表找到元素并访问其值。表迭代器的概念就用于解决这个问题。

6.2.1 迭代器的概念

表迭代器是一个对象,她按表中元素的位置次序访问元素。可以把迭代器想象成在表元素范围内来回滑动的定位器。在表中的任意位置,迭代器都能访问相应元素的值。使用到上一个和下一个元素的链接,迭代器能够一次左右移动一个位置。迭代器是一种一般的指针,在接口中使用指针符号。用反引用运算符*访问迭代器定位的元素的值。增量运算符++、-- 重置迭代器,使其指向表中的下一个(上一个)元素。运算符 == 、!= 比较指向表中元素的两个迭代器对象。如果另个迭代器指向表中相同的元素,则他们是相等的;指向不同的元素,则不相等。

list::iterator                操作

*                                 访问迭代器当前指向的项的值

++                             移动迭代器到表中后一项

--                                 移动迭代器到表中的前一项

==                               当两个迭代器指向同一项时,则返回TRUE

!=                               当两个迭代器不指向同一项时,则返回TRUE

声明和使用迭代器:list类把迭代器作为嵌套类包含在声明中。因此,迭代器对象的声明必须把类名“iterator”和作用域运算符表达式“list ::”放在一起。作用域运算符指出迭代器属于list类。所有STL容器类都有一个嵌套的iterator类。在容器中声明iterator类指明了iterator类属于容器。迭代器用容器结构的知识通过*运算符访问元素,通过++ 、 -- 运算符扫描运算符扫描元素。表迭代器利用表按位置存储元素的事实扫描整个序列。

// 表迭代器声明

list ::iterator iter ;

与C++指针一样,迭代器对象有了初始值才有效。程序必须把迭代器与特定表中的特定位置联系起来。为了初始化表迭代器,list类提供了两个成员函数:begin()和end();begin()返回指向表开始位置的迭代器值。end()函数返回指向表尾下一个位置的迭代器值。注意:::end()函数是表尾的下一个位置,而不是表的最后一个元素(尾部)的位置。

注意::表迭代器在表中以循环放式移动。当一个迭代器指向end()时,运算符++移动迭代器到位置begin()的一个表元素。类似的,当迭代器在begin()时,运算符--将她移动到位置end();

6.2.2  常量迭代器

C++用const来指示不能被改变的对象。const特性也可用于表迭代器。STL表有另一个常量迭代器,其作用与一般的非常量迭代器一样,但他有一个显著的特点:程序员不能在赋值语句左边的常量迭代器中使用反引用运算符* ;常量迭代器不能用于表的insert()和erase()函数,因为这两个操作都改变表。

在list类中,常量迭代器的对象类型名为const_iterator 。与非常量迭代器一样,常量迭代器在其声明中包括域运算符表达式:  list ::  。

list ::const_iterator  iter  ;

常量迭代器用运算符++ 、 -- 在表中来回移动。 * 运算符允许常量迭代器访问表中元素的值,但不能更新值。迭代器和const_iterator对象有不同的类型,因此,list类给常量迭代器提供了独立的begin()和end()版本来指示表中的极端位置。决定使用常量迭代器还是非常量迭代器的规则很简单:用常量迭代器访问和扫描常量表,用非常量迭代器访问和扫描非常量表。

list类                                               操作

iterator begin()

const_iterator begin()

iterator end()  不能用*对end()值进行反引用

const_iterator end();不能用*对end()值进行反引用

 

6.2.3  顺序查找表

此函数把iterator范围[first , last) 和类型T的目标值作为参数。如果有与目标值匹配的元素,则返回值为指向范围内第一个匹配元素的list ::iterator 。 如果没有匹配值,则返回值为迭代器值last。

函数原型为:

template
list ::iterator  find(list ::iterator  first , list ::iterator  last , const T& target)
{

}

表版本不需要表对象作为参数,因为迭代器first ,last 指示表中的位置。使用反引用运算符*,迭代器可以访问表中元素。

迭代器是在表中声明的嵌套类。如果没有帮助,则C++编译器可能无法为find的迭代器参数确定模板类型T。当调用函数时,把实际的模板类型放在函数名后面的角括号里,告诉编译器类型是什么。

例如:iter = find (intList.begin() , intList.end() , 5)  ;

通常,无论何时编译器不能为函数调用确定模板类型时,都可以用这种结构,指示编译器使用指定的类型。

    fin.open(fileName.c_str());  //fileName为string
//     basic_string::c_str
//         const E *c_str() const;
//     The member function returns a pointer to a nonmodifiable C string
//     constructed by adding a terminating null element (E(0)) to the controlled
//         sequence. Calling any non-const member function for *this can invalidate
//         the pointer

6.3  表插入和删除操作

list类                                  操作

void erase(iterator pos);       删除pos指向的元素

void(iterator first , iterator  last) ;         删除迭代器范围[first , last) 内的所有元素。

iterator  insert(iterator pos , const T&  Value);      在pos前插入Value ,返回表中指向新数值位置的迭代器。这个操作不影响现在现有的迭代器。

在erase()函数中,程序员可以在迭代器参数中使用++运算符。这样做有两个结果:迭代器的当前值成为erase()的参数,然后迭代器移动到表中的下一个元素。结果是很明显的。增量运算符使迭代器指向表中的下一项,即紧跟被删除元素的项,在erase执行后该迭代器任然是有效的。

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值